The review of SE-0380: if
and switch
expressions ran from December 7th to December 30th. Feedback was generally positive; many reviewers noted that the usability of if
expressions in other languages is missed in Swift, and selection statements producing a single value in each branch is a common pattern across their Swift code. Most of the discussion focused on whether the narrow scope of the proposal is an acceptable resting place for if
and switch
expressions.
Overall, the Language Workgroup believes that SE-0380 is a valuable usability improvement that reduces unnecessary ceremony in a very common pattern across Swift programs. The Language Workgroup has decided to accept the proposal with the modification to ban all non-error-handling control flow in if
and switch
expressions.
I have enumerated the specific details of the proposal that were the focus of constructive discussion below, along with the Language Workgroup’s decision and justification on each point.
Type inference across if
and switch
expression branches
SE-0380 proposes isolated type inference across branches of if
and switch
expressions, meaning types in one branch cannot influence type inference in another branch. Reviewers noted that this type inference behavior is different from the ternary operator, which may be unexpected.
The Language Workgroup believes that isolated type inference for if
/switch
expression branches is a reasonable resting place for SE-0380. Enabling full bidirectional type inference for if
and switch
expressions would proliferate an existing type checking performance pain point in Swift — notably, a problem that does not exist with the statement form of if
and switch
, which may make it more difficult to transition from a statement to an expression.
The Language Workgroup also acknowledges the value of bidirectional type inference, and encourages exploring bidirectional type inference for results of if
/switch
expressions, opaque result types, and multi-statement closures in a later proposal, perhaps in a more limited form. This exploration can be informed by real-world adoption of these features, and existing code can be used as a baseline for type checking performance impact.
Allowing return
out of if
and switch
expressions
SE-0380 proposes allowing return
statements in if
and switch
expressions to return out of the enclosing function. Many reviewers noted that this behavior is unexpected, and they anticipate control flow out of expressions to become a source of bugs.
The Language Workgroup agrees that new control flow out of expressions is unexpected and error-prone. Swift currently only allows control flow out of expressions through thrown errors, which must be explicitly marked with try
as an indication of the control flow to the programmer. Allowing other control flow out of expressions would undermine this principle. The control flow impact of nested return
statements would become more difficult to reason about if we extend SE-0380 to support multiple-statement branches in the future. The use-cases for this functionality presented in the review thread were also fairly niche. Given the weak motivation and the potential problems introduced, the Language Workgroup accepts SE-0380 without this functionality.
Multiple-statement if
and switch
expression branches
Much of the review discussion centered around the single-expression limitation of if
and switch
expression branches. Reviewers noted that programmers will expect the ability to evolve a single-expression if
or switch
into one with multiple statements in its branches, similar to evolving a single-expression closure into one with multiple statements in its body.
The Language Workgroup believes that multiple-statement branches for if
and switch
expressions are a compelling direction for Swift. Evolving single-expression bodies into multiple statements is a very common workflow; a common example is adding a logging statement inside such a body. Requiring workarounds using an immediately-executed closure or reverting back to the statement form of if
or switch
is a suboptimal programming experience.
There is significant design space to explore for enabling multiple statement if
and switch
expressions, and further discussion on whether implicit returns should be extended to function bodies with multiple statements. The Language Workgroup believes SE-0380 is valuable enough on its own — similar to the value of single-expression closure type inference despite the longstanding limitation on multi-statement closures that was lifted in SE-0326 — and has decided to accept the single-expression limitation while the design space for multiple statement branches is explored.
Extending other statements to have expression forms
SE-0380 only supports expression forms of if
and switch
statements; other statements are not included. Reviewers noted that other statements, such as do
statements, would also be valuable as expressions. The Language Workgroup believes that introducing expression forms of other statements would be useful in future proposals, and narrowing SE-0380 to selection statements is an appropriate scope. do
expressions are also much more expressive with multiple-statement support, so exploration of the multi-statement design space will likely inform future generalization to other statements.
As always, thank you to everyone who participated in the pitch and proposal review. Your contributions help make Swift a better language.
Holly Borla
Review Manager