# \`if {} else {} else {}\` actually works when combining if expressions with guard

**URL:** <https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766>\
**Category:** Using Swift\
**Tags:** guard, if-expressions\
**Created:** [March 18, 2024, 8:37pm UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766 "2024-03-18T20:37:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [March 18, 2024, 8:37pm UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/1 "2024-03-18T20:37:24Z")

</div>

```swift
let getter: () -> String? = {
    MainActor.assumeIsolated {
        …
    }
}

guard let text = if Thread.isMainThread {
    getter()
} else {
    DispatchQueue.main.sync(execute: getter)
} else {
    return false
}

```

Ignore the use-case, just look at the syntax. I would have sworn this was explicitly not allowed, yet Swift 5.10 accepts it without so much as a whimper.

It feels like it probably shouldn't… just a bug / oversight?

Although I could see an argument for this being no worse, ultimately, than having to shove a whole bunch of extra parentheses in there too (which is what I expected the compiler to force me to do, as it usually does).

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 18, 2024, 9:36pm UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/2 "2024-03-18T21:36:56Z")

</div>

I don't think that's a bug per se. Consider a simpler example with nesting that shows what going on:

```swift
func foo(condition: Bool) -> String {
    guard let text =
        if condition {
            "1"
        } else {
            "2"
        }
    else {
        return "3"
    }
    return text
}

```

What does look a bug here is that "guard let text = " doesn't check that the following expression is a non-optional String... Ideally it should complain with "RHS expression is not optional".

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [March 18, 2024, 10:16pm UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/3 "2024-03-18T22:16:05Z")

</div>

Trailing closures are banned in `if` but not `guard` for the same sort of reason: the block immediately after something condition-shaped is usually the body, but for `guard` there’s an `else` there to keep it from being two braced blocks right up against each other. So it wouldn’t have been completely unreasonable to require parentheses here. Since it’s now been released without that requirement, though, I don’t know if it’s worth adding it (though formatters or linters might want rules about it).

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 18, 2024, 10:27pm UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/4 "2024-03-18T22:27:02Z")

</div>

We can't do parenthesis yet anyway (if expressions are only allowed in certain limited contexts):

```swift
let x = (if condition { 1 } else { 2 }) // 🛑 'if' may only be used as expression in return, throw, or as the source of an assignment

```

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [March 19, 2024, 3:08am UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/5 "2024-03-19T03:08:40Z")

</div>

Yeah, exactly - I wish if & switch expressions weren't so restricted, as that ironically causes _more_ problems with bad / ugly syntax than it seems to solve. Plus they're so useful sometimes - I particularly do not like that I can't use them inline for arguments of function calls, since they're sometimes much easier to read than the ternary operator.

"Pointless" temporaries / local constants aren't the end of the world usually, but they have knock-on effects like disallowing use of expressions (as opposed to statement blocks), so occasionally what would otherwise have been pretty concise and neat ends up exploded into two or three times more verbage.

Anyway, I was expecting more of a reaction to this double-else situations, but evidently it doesn't bother folks too much (and as @jrose notes it's probably too late to change it anyway), so I'll just not use in my code and move on. 😄

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 19, 2024, 3:22am UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/6 "2024-03-19T03:22:12Z")

</div>

> [@wadetregaskis](#):
>
> Anyway, I was expecting more of a reaction to this double-else situations, but evidently it doesn't bother folks too much

Probably because we've seen it before ;-)

```swift
char* foo(bool a, bool b) {
    if (a) if (b) {
        return "1";
    } else {
        return "2";
    } else {
        return "3";
    }
}

```

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [March 19, 2024, 3:28am UTC](https://forums.swift.org/t/if-else-else-actually-works-when-combining-if-expressions-with-guard/70766/7 "2024-03-19T03:28:53Z")

</div>

Huh, I've never encountered that before. I wouldn't have guessed that C has this problem too.
