SE-0380: `if` and `switch` expressions

To clarify, as currently proposed, if/switch expressions do not have to be marked with try or await if the branches may throw or suspend, as those actions will be explicitly called out within the branches themselves with try/throw/await. For example, you can write:

func foo() throws -> Int {
  let x = if .random() {
    throw SomeError()
  } else {
    5
  }
  return x
}

and:

func foo() throws -> Int {
  let x = if .random() {
    try someThrowingFunction()
  } else {
    5
  }
  return x
}

without writing try if.

I thought this was mentioned in the proposal, but it seems like it isn't. It did however come up in the pitch thread.

If we were to enforce try if/await if, then I agree it might make sense to ban return, as there's no equivalent keyword to mark the expression. However I'm not convinced that we should enforce try if/await if, as IMO it would be unnecessary noise, especially for the cases currently being proposed (bindings, implicit returns, etc.). As such, banning return while allowing throw and try would seem odd to me, as they are all able to exit the function, and are just as explicit as each other.

I mean, this is true of any refactoring where you're taking code that was previously in a closure and bringing it into a parent function, I'm not convinced it's sufficient grounds to outright ban return in if/switch expressions.

That being said, I'm not against banning return for now and re-examining it when we consider allowing if/switch expressions in arbitrary positions (where IMO return may be more contentious).

4 Likes