The discussion so far has given me a chance to organize my thinking, so here’s 
a more complete train of thought.

I get that people don’t like extra punctuation.  The commonly rejected 
proposals, however, make it clear that braces are here to stay and we should be 
designing the syntax right now with that in mind.  It took me a long time to 
get used to not using them in Python, now I’m getting used to using them again 
in Swift.  Swift has a long life ahead of it, and there are going to be plenty 
of places where the syntax is going to become inconsistent in the service of 
supporting new features.  Now is when we set the starting point though and try 
to set ourselves up in a way that requires a minimum of syntax goofs in the 
future.


—=Philosophy=— 

As philosophical backdrop, here’s the link on removing braces in the “commonly 
rejected proposals” section:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003656.html

I’ll pull out two quotes from that post, one from Kevin Ballard:
"There is not in fact an emphasis on conciseness. This has been repeated many 
times by the swift team. Conciseness is not a goal of Swift, but expressiveness 
absolutely is. Braces are a well-understood and simple way to express the 
notion of a scope/closure.”

and another edited as suggested by Chris Lattner:
"'Be like C' isn't a goal either of course, but when deciding between two 
alternatives that have no compelling arguments either way, picking the one that 
is most familiar to programmers in the extended C family is a good idea."


So, from that I take:
1) braces indicate scoping
2) conciseness isn’t an end in itself
3) we should err on the side of being Cish when no other arguments prevail.




—=In C `cases` Aren’t Scopes, in Swift They Are=—

Starting from what’s Cish, here’s a snippet of Swift code:

let x=5
switch x {
  case 3:
    let y=5
    print(x," ",y)

  case 5:
    print("Two",x,"s”)

  default:
    print(“default")
}


This runs fine and prints “Two 5 s” to the console.

This is something similar in C:

int x=5;
switch (x) {
  case 3:
    int y=5;
    printf("%d %d",x,y);
    break;

  case 5:
    printf("Two %d s",x);
    break;

  default:
    printf(“default");
}


This code fails.  C gives me an error pointing at `int y=5;` complaining that 
it expected an expression there.  C++ gives me an error that it can’t jump to 
`case 5:` because it would skip over the declaration of `y`.

I can fix this in both C and C++ by wrapping the `case 3:` in curly braces, 
creating a local scope:

int x=5;
switch (x) {
  case 3:  {
    int y=5;
    printf("%d %d",x,y);
    break;
  }

  case 5:
    printf("Two %d s",x);
    break;

  default:
    printf("default");
}

This code compiles fine in both C and C++.  A new scope has been delimited and 
created, and `y` only exists in that scope.


So, by both criteria 1) and 3), Swift should be using braces on `case` 
statements.  Each case is a scope unto itself, and the extended C family of 
languages would require braces in that event.





—=Conciseness, Ugliness and Nested Braces=—

Conciseness is not an emphasis of Swift, but even if it were then this is not a 
particularly in-concise change to the syntax.  The suggestion here is to remove 
one punctuation mark and add two for a net gain of 1 character.  This doesn’t 
strike me as unduly burdensome.

The better arguments are those on aesthetics and ease of use.  Each of these 
seems to focus on opposite situations.  The ugliness is when there is only one 
line per case, the ease of use challenge is when there are many and the 
developer needs to determine how many braces to close.

How common is it to have a single line per case?

Aesthetics, at least, are mostly subjective.  Ease of use, in part, depends on 
habits.  In both cases, however, I’d argue that the aesthetically preferable 
design, and the method least likely to introduce errors, is the one that is 
most consistent with the rest of the language.  Things tend to be uglier when 
they stand out as unusual, and habits force us to follow patterns, introducing 
errors when the pattern doesn’t hold.

From that perspective, this is what Swift looks like everywhere else:

if x = 3      { print(“Three”) }
else if x = 5 { print(“Five”) }
else          { print(“Default”) }

It also doesn’t shy away from nested braces:

var x:Int {
  get { return _x }
  set { _x = newValue }
}


Aesthetically, is it less ugly to have some scopes require braces and others 
not?  I really thought the square bracket messaging syntax of Obj-C was ugly 
until I got used to it because square brackets were for subscripting and looked 
“heavy” for method calls.  

From an ease of use perspective, it is more likely to forget to add a closing 
brace when braces are used everywhere, or to accidentally add one in the one 
place they aren’t?




—=What Isn’t Like C Shouldn’t Look Like C=—

There’s also the point that `switch` statements in Swift aren’t the same as 
those in C.  The different scoping rules are one difference. The lack of 
default fall through is another.  And of course the additional capabilities of 
the `case` condition itself.

For those reasons, deviating from the C syntax might not only be justified, but 
desirable as a notational reminder that this isn’t your father’s `switch` 
statement.  The closing brace in particular gives a visual cue that fall 
through isn’t going to happen.




—=Leaving the Door Open for a `switch` Expression=—

Another commonly rejected proposal is the request for a `switch` expression:
https://lists.swift.org/pipermail/swift-evolution/2015-December/000393.html

To my eyes, the rejection of this proposal is not as iron clad as the rejection 
of removing curly braces.  Here’s a quote from Chris Lattner:

"FWIW, I (and many other people) would like to consider turning many 
statement-y things in swift into expressions.  I’d love to see the weird ?: 
ternary operator get nuked and replaced with an if/else expression of some 
sort.  This is an area that the apple team hasn’t had bandwidth to consider 
carefully.

That said, there are challenges here in the details.  How will the grammar 
work?”


I think wrapping the `case` statements in curly braces in the statement version 
of `switch` gets us closer to a reasonable answer for how the grammar might 
work on an expression version:  the expression version would be delimited with 
colons similar to how the ternary operator is.

Something like this might work:

let s:String? = switch x 
                case 3: “Three” 
                case 5: “Five” 
                default: nil

In the expression, the `case` clauses don’t represent scopes and shouldn’t be 
curly braced so the colons give a nice syntactic distinction.

I’m not holding by breath for such a feature, but this change to the `switch` 
statement makes such a thing easier to adopt.





> On Jul 10, 2016, at 13:37 , Dennis De Mars <dem...@fractaldomains.com> wrote:
> 
> I don’t like this idea at all. The current switch syntax is really clean, one 
> of the nicest parts of Swift, and this would really turn it into something 
> messy.
> 
> I’ll make a possibly controversial statement here: one of the worst aspects 
> of C syntax, which is unfortunately perpetuated by many modern languages, 
> Swift included, is the use of curly braces everywhere to demarcate every kind 
> of block: every control structure, every data structure and every function 
> body.
> 
> This leads to a proliferation of nested braces which all have to be placed 
> correctly in order for the code to be correct. Of course, we all use 
> indentation to help manage this, but I think we all know that once the 
> closing brace is sufficiently far from the opening brace, it becomes 
> difficult to tell which brace matches which even with indentation. I think I 
> spend a significant amount of my development time just eyeballing those 
> closing braces. Of course, we also have editor features to help match them up 
> but relying on such editor features might be an indication of a flaw in the 
> language. At any rate, it impedes readability of the code, editor or no 
> editor.
> 
> Not having the braces for each case is, to me, analogous to the way Swift 
> removed the outermost parenthesis in the if statement conditional part. When 
> you have a complex conditional expression with nested parentheses, removing 
> that unnecessary outermost pair really improves readability (and reduces 
> possibility of error). This can be done because the outermost parentheses 
> aren’t really necessary to demarcate the boundaries of the expression.
> 
> Similarly, the case keywords in the switch statement sufficiently demarcate 
> the extent of the statement block; it is unnecessary to toss in an extra pair 
> of these brace characters that may already be heavily used in the statement 
> block itself.
> 
> I think the extra burden on readability (and writability) of having the extra 
> pair of nested braces is not justified by the desire for consistency. If 
> consistency is so important, then rather than detracting from the quality of 
> the switch statement by adding the braces, why don’t we improve the quality 
> of the rest of the language by getting rid of some of those braces in the 
> other constructs that use them! (Note: I don’t really expect that to happen…)
> 
> - Dennis D.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to