[swift-evolution] [proposal] Allow trailing closures in 'guard' conditions

Xiaodi Wu xiaodi.wu at gmail.com
Thu Mar 24 03:05:34 CDT 2016


Certainly, `while expr do { code }` is clever, but it could still get hairy:

```
func foo(_ bar: Int) -> Bool {
  return true
}

func foo(_ bar: Int, baz: () -> Void) -> Bool {
  return false
}

// what's going on here?
while foo(42) {
  code
}
do {
  much code
}
catch {
  code
}
```

You've got to read pretty far to know which foo is called! Let's say
we stipulate that we'll use another word instead of `do`. Maybe we
choose something not a reserved keyword: `while expr frobnicate { code
}`. Better, until you have a function `frobnicate(closure: () ->
Void)`, and then you could run into problems again. Maybe we stipulate
that `do` must be on the same line as the closing brace. Well, first
off, that would be inconsistent. It was settled on this list a while
back, I believe, that the preferred style in Swift is:
```
if expr {
  code
}
else { // else on its own line
  code
}
```
Likewise, I'm allowed to write (although I recognize that this isn't
the most common style in which it's written):
```
guard expr
else {
  code
}
```
So the same-line rule would be inconsistent. Suppose we forbid
newlines before else for consistency--even then, I would argue that
clarity for the human reader is not greatly improved. I'm not yet
convinced that trailing closures in these situations are so desirable
as to be worth this syntactic muddling. Limiting trailing closures to
guard expressions alone doesn't raise any of these issues.


On Wed, Mar 23, 2016 at 11:54 PM, Chris Lattner via swift-evolution
<swift-evolution at swift.org> wrote:
>
>> On Mar 23, 2016, at 8:11 PM, Dany St-Amant via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>> A fourth alternative would be to change the syntaxes of `if` and `while` (and probably `for` and `switch`) to also have a keyword in this position.
>>>
>>>      if expr then { code }
>>>      while expr do { code }
>>>      for elem in expr do { code }
>>>      switch expr among { code }
>>>
>>> I'm not going to say I advocate for this option, but it *would* clearly mark the end of the condition so that trailing closures could be brought to all of these statements, so it seemed worth mentioning.
>>
>> Could such new keywords be optional, only required when the compiler see the construct as ambiguous?
>
> No.  If the compiler could tell when the keyword was necessary, we just wouldn’t require it! :-)
>
> The other approach you could take is to only use this sort of keyword when a trailing closure is present, but at that point, you might as well just wrap the trailing closure with parentheses (which is already supported today, and the compiler now nudges you towards).
>
> -Chris
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list