Coming back to the review thread after the pitch thread a while ago 
Overall +1, this is a good step. I'm hopeful for the future directions to materialize as this feels like only a partial step, but in the right direction, so I'm in support of this small step in the right direction.
Independent branch typecheck
This is honestly fine. I've worked with if/switch expressions that unify the types of branches in Scala and it definitely is true that it works very well there, it also has weird edge cases, unifying to things like Serializable
, Product
or Any
... I don't think this is a big of a deal being a bit strict here should be fine -- and it is a decision that can be revisited in the future if we had to.
It is definitely true that both branches having the same type is the most common case to deal with here.
As far as I understand, the following is possible, right?
let x: Int? =
if p {
nil
} else {
2
}
if so, that addresses a lot of the cases one may have to deal with types which aren't exactly the same on both branches, but end up as the same when the whole expression is assigned to x
.
Requiring else
This is good. The alternatives are confusing, and overall lead to more ?
everywhere where you might not really need it. I think it is good to force the if
to always have an else
so that if I want an optional, I'll spell it out.
Overall, personally, if without else always is a bit of a worrying thing I need to double-check, so this seems good to enforce.
Single line -> multi-line
I'm not a huge fan of the "single line" special cases of things for reasons that the proposal itself already acknowledges with the "unfortunate usability cliff" explored in Multi-statement branches.
The reality is that a lot of code uses logging, tracing, metrics everywhere and by limiting this feature to single lines, we're adding a lot of friction to doing the right thing (yes, do add that log statement; do add that metric, do add that coverage probe).
So if there's a single piece of the proposal I'd push harder on, it's this. But the proposal authors requested to scope this out into a future discussion so that may have to wait.
Alternate syntax, deprecating ternary etc
I agree with the authors in that I don't think new syntax is viable or advisable here; Swift can perfectly well accommodate this pretty "normal" by nowadays modern language standards feature in existing syntax.
Ternary is fine to let be, it'd just cause needless crunch to deprecate it; but one would hope to see it much less in future Swift code being written 
Nitpicks
While this is possible in Scala, it's an anti pattern. return
has some horrible meanings in Scala and is best avoided entirely. See here why return
is terrifying in Scala: Scala Puzzlers
Scala puzzler: return is horrible
def value: Int = {
def one(x: Int): Int = { return x; 1 }
val two = (x: Int) => { return x; 2 }
1 + one(2) + two(3)
}
this returns 3
Though since recently this causes a warning: Non local returns are no longer supported; use scala.util.control.NonLocalReturns instead
Anyway, with Swift's current return
semantics I believe this is fine, let's support this:
init?(rawValue: String) {
self = switch rawValue {
case "foo": 1
case "bar": 2
case "baz": 3
default: return nil
}
}
as @Ben_Cohen mentioned in SE-0380: `if` and `switch` expressions - #55 by Ben_Cohen
Overall
As we further explore this space and fix the remaining issues in future proposals, I suggest we lean harder on languages like Scala, which have gotten fleshed out a long time ago. The proposal has been leaning hard on Java as example cases, but I think that's not a good source of inspiration because everything it did with expressions has been inspired by Scala and adapted to "how do we make it feel JAVA" which isn't a goal for us, so instead we should be learning from more expressive languages as sources of inspiration, and not less expressive ones that adopted these things in their modified ways.