Swift's syntax could have fewer parenthesis and commas
| Originator: | bigzaphod | ||
| Number: | rdar://17185400 | Date Originated: | June 5, 2014 |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | |
| Classification: | Enhancement | Reproducible: |
(Caveat: I have not yet implemented anything significant in Swift)
I think Swift could do with making more of the parenthesis and commas optional except when absolutely needed and for that style to become the official “Swift Style.” I think it would feel a lot cleaner (to me and probably others).
I’ve also noticed that it seems to be “Swift Style” to put spaces after colons on named parameters. I feel as if this is wrong as it creates a visual separation between the label for the value and what the value actually is. In my mind, the label/name for a parameter is an annotation added to the value. I consider the name of the parameter almost as if it were wrapping an aspect or trait around the value itself before sending it off to the method. It’s as if I am saying, “In this context, this value is a ‘width’.” Personally, I think it should be a syntax error to have a space between the name and the value - but maybe that’s just me!
Here’s some examples for how I’d transform the syntax:
// Swift
var containerView = UIView(frame: (CGRect(x: 0, y: 0, width: 100, height: 200)))
containerView.addSubview(resultView)
containerView.insertSubview(backgroundView, atIndex: 0)
resultView.value = pow(sqrt(42), 2)
// MySwift
var containerView = UIView frame:(CGRect x:0 y:0 width:100 height:200)
containerView.addSubview resultView
containerView.insertSubview backgroundView atIndex:0
resultView.value = pow (sqrt 42) 2
I haven’t thought this all the way through, of course, but not only is this syntax shorter in places, but it doesn’t have nearly as much visual noise (IMO) with the parenthesis and commas floating around. Parenthesis now have only two purposes - to group units of thought, and to declare order of operation.
Function application becomes the default “action” at the start of every statement with parameters separated by spaces (even control-flow constructs like “if” or “for” would look and feel a lot like normal functions as a result).
For functions with unnamed parameters (such as pow), commas could be optional if they might help visually communicate that multiple parameters are being chained together:
resultView.value = pow (sqrt 42), 2
You could even continue to write code in the more “familiar” way with this approach because the parens are only grouping constructs and don’t carry any other implicit meaning for function application, so you can add them anywhere, really:
resultView.value = pow (sqrt (42), 2)
And of course assuming the spacing wasn’t enforced, you end up with traditional syntax:
resultView.value = pow(sqrt(42), 2)
Or even wrap the all functions in parens all the time if you like LISP and/or miss Objective-C’s groupings of things together:
resultView.value = (pow (sqrt 42) 2)
(containerView.insertSubview backgroundView atIndex:0)
Another advantage is that custom control-flow constructs would then look exactly like the ones built into the language itself. It was demonstrated a few times during WWDC sessions how you can add extensions to classes or structures and create what amount to custom control-flow, but current Swift syntax is such that your custom control flow will never feel as natural as the built in control flow because you cannot omit some of the parenthesis. Let’s say we have a function named “repeat” which takes a block and it will call the block the given number of times:
repeat(42, { /* block */ })
You can also write it like this which is looking very close to control-flow:
repeat(42) { /* block */ }
But it’s not *quite* control-flow because it looks like this with built-in control-flow:
for 0..42 { /* block */ }
So, if you dropped the parenthesis for function calls, the repeat function could in fact end up looking just like it:
repeat 42 { /* block */ }
I find that highly appealing!
If you have a function which takes no parameters and you want to call it, then to distinguish between actually calling it vs. referencing it, you add an old-fashioned semicolon to the end (which would be optional whenever you have a function with parameters):
resultsView.layoutIfNeeded;
Whereas if this appeared on it’s own, it would just be a reference to the function layoutIfNeeded and would generate an error:
resultsView.layoutIfNeeded
However this would work and call the layoutIfNeeded function on the resultsView 42 times:
repeat 42 resultsView.layoutIfNeeded
And this would be potentially ambiguous, but is probably solvable by messing with the precedence of the semicolon so that it would do the same as the above line:
repeat 42 resultsView.layoutIfNeeded;
Whereas this would be an error because layoutIfNeeded doesn’t return a block:
repeat 42 resultsView.layoutIfNeeded;;
Etc. etc. Anyway, I think it’s worth considering this. Perhaps you already have - but I really dislike the idea of trading one kind of visual noise (square brackets everywhere) for another (parenthesis and commas and unattached named parameter labels everywhere).
Thanks for listening. :)
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!