[Pitch] Last expression as return value

The cost of distinguishing between these two kinds of if is truly negligible compared to the rest of the compiler (most of the work is early in the relatively low-cost part of the pipeline). And in particular, this extension of it doesn't increase the cost of them.

One of the explicit design goals of SE-0380 was to avoid creating a constraint system comprising the whole of the if expression. There is no backtracking from the second branch and back to the first. That's why this doesn't compile:

let maybeInt =
  if .random() {
    1
  } else {
    // error: 'nil' requires a contextual type
    nil
  }

You must provide enough type context to avoid needing to backtrack from the nil back to the 1 to determine that the type is actually Int?. (let maybeInt: _? = is enough to tell the first branch it's an Int?)

This is in contrast to the ternary operator where this compiles just fine:

let maybeInt = .random() ? 1 : nil 

but requires that backtracking.1 would be an Int by default, then the nil invalidates this and requires re-evaluating the 1 as an Int?. This can be the source of lengthy compile times, especially when combined with other operators (using ternaries in more constrained environments, like in argument position, is generally much better).

Similarly, one of the (lesser) motivations of this pitch is to discourage the current slight nudge towards long compound expressions in order to be able to stick within the single expression rule for closures, especially since closures themselves end up getting incorporated into bigger constraints, leading to longer compile times and enigmatic diagnostics when they have errors.

6 Likes