Guess your team never used Perl, where every code block can have an implicit return -- the last line of code.
In general, syntactic sugar has been the lowest priority for Swift Evolution. Lately, there have been a number of changes in this area to support the articulated goals for Swift 6:
Towards this vision, there are three language areas which are particularly important to focus on:
- Round out capabilities in the language that support building expressive and elegant APIs such as variadic generics and DSL capabilities like function builders
- Refine Swift’s implementation and capabilities to allow it to be used for low-level systems programming (or in constrained environments) and in important domains like services and machine learning
- Provide excellent solutions for major language features such as memory ownership and concurrency
However, unless your change can fit into the grander vision, it's probably out of scope if it's purely syntactic sugar.
Honestly I would prefer ' => ' to the return operator being used already ' -> '.
I'm -1 on this pitch, and I don't have much to add to what others posted above except one more point:
Using this syntax would make it too easy to accidentally break the compatibility for any other code reusing your library.
Let's say you have two functions and one of them calls the other like this:
private func implementationDetail() -> Int { ... }
// ...
public class SomePublicClass {
func doSomething() -> implementationDetail() // returns Int
}
and for some reason you decide that your private function should return Int?
instead of Int
, so you change the return type:
private func implementationDetail() -> Int? { ... }
// ...
public class SomePublicClass {
func doSomething() -> implementationDetail() // oops! returns Int? now
}
Your code still compiles, but the public interface has changed and anyone using this function from their own code will no longer be able to compile it.
As others pointed out above, a similar syntax exists in the Kotlin language, and the compatibility issue is one of the reasons its usage is often discouraged, especially in complex projects.
This sugar might look great in the demos, but I believe that in the real projects its benefits are practically non-existent.
Brainstorming some ideas to get around that issue:
- Don't infer the return type. Granted, this gets you stuff like
func something() -> Int => otherThing()
which is more awkward than in C# where the return type is before the function name. I'm assuming the proposal includes the option to have explicit return types anyway. - Warn on inferring the return type for public functions and properties. It could be either a compiler or linter warning.
- As a user level approach, use protocols for your public interface, so all your return types are explicit.
In addition to the concerns about syntactic sugar, this proposal would also have a significant impact on compile time. Referring to the sum
decl above would require type checking the body of the function, instead of just looking up the declared type. We have tried hard (but haven't completely succeeded, e.g. properties with inferred type (var x = some_expression
)) to make it so we can have modular type checking of function bodies.
In addition to making compile times fast, this is really really important for IDE performance, where you want to be able to do fast incremental parses of a subset of the current file/module.
Side note: what's the status on variadic generics? Is this still a priority? I remember some work being done on this last year but it seems to have fizzled out
I'm a definite -1 on this. I see this as an unnecessary change that will add a new type of syntax you need to learn that is different from what Swift developers are used to.
There is no need to remove curly brackets. It doesn't make code more readable. -> is two characters and {} is two characters, so it doesn't make typing faster. -> is already used to declare return types.
Having two syntaxes for every feature in the Swift language is really creating a messy language. There seems to be a never ending pursuit of "let's remove x" because "it looks cleaner". I can't imagine what the hoops the parser is going to have to jump through in two years when we decide to remove the 'var' and 'let' keys to make code 'cleaner to read'.
The sad thing is that this is becoming a losing argument for proposals now. The feeling among the community is starting to be "let's rip out as much as possible and make everything do two other things for the sake of not happing to type a couple of characters and call it 'more clear'".
Omitting return should have never been accepted and trailing closures should have been removed as a feature a long time ago along with currying.
How ‘bout we call it be
, and have the compiler figure it out...
I disagree with both: return
for single line function/subscript/computed properties bodies is redundant; also, parentheses and commas are mostly redundant, and trailing closures remove the need for both. But writing out a function signature in full is not.
Or also, I 100% agree with SE-0257: commas for multiline expression lists are redundant, like semicolons to for multiline statements are.
To be clear, by "redundant" I mean "there's something else already that clearly provides that information while reading code".
Braces to identify function bodies are not redundant because you don't have another thing that does it: to remove them in some cases, we need another clear way to signal what are the beginning and the end of function bodies. In my experience I literally never found a convincing argument for removing braces from code for cases like this.
I also write Kotlin and review Kotlin code, and save for some simple cases (e.g. guards like if (something) return somethingElse
) I find that losing braces mostly makes code harder to read and understand, and I'm usually able to convince my colleagues that for maintainable production code it's better to put those braces in place (even if it looks less "cool").
I would add that it's not just function bodies. Swift consistently uses braces to delineate code blocks of all kinds.
We don't allow
if condition
statement
and for good reason.
I agree. The only case where I would maybe accept losing the braces is in cases of single line, single statement guard
s, like:
guard condition else return nil
I doubt we need such a feature — but to relativize the quite strong backlash:
I don't think the status quo is that great either.
Some languages always propagate the result of the last statement in a block, some always force you to be explicit; I don't know any other language which has the same inconsistency as Swift.
You can put as many expressions as you like between a pair of curly braces, and there is absolutely no indication that there is a special treatment for one case; if Swift already had something like this pitch, we'd most likely be all happy with it, and very few would seriously consider adding exceptions for single-expression bodies.
However, given the current compatibility-concerns, it's very unlikely that breaking changes are accepted (but afaics that still leaves the "everything is an expression" approach on the table... ;-).
There should be no single line guard
statements. There should be no single line if
statements. Clarity over terseness. This Pitch is -1 too.
I agree that single line if
statements are generally a bad idea. But guard
enforces returning from the function, so when I encounter one in code I already know that the code execution is not going to proceed if the condition is not met.
I currently write code like this:
guard thisShouldBeTrue else {
return
}
This is a case where braces are redundant: no information is added by the braces and the newline if the only thing I'm doing is returning, and I know that I must return
(or throw
or any other statement that causes an early exit) so I'm expecting it. The following seems to me more clear:
guard thisShouldBeTrue else return
While it is an "inconsistency", in the sense there is a special case, I don't think that's problematic at all: it's a non-obvious aspect of the language that must be learned, but the alternatives are worse in terms of code clarity. We talked about this at large at the time of SE-255 so I don't intend to do it now, but I think Swift is better than many other languages here: consistency isn't everything, and Swift (concerning the implicit returning rules) hits a sweet spot between clarity and terseness. If anything, the next step would be extending the same kind of behavior for all other statements with braces (for example, treating if-else
as an expression when there's a single expression in the branches).
-1 The cognitive burden for parsing Swift is high enough already. Overloading the meaning of ->
to eliminate braces would only serve to add another barrier to understanding.
I too am -1. IMO the example provided:
isn't that 'swifty'.
Additionally, omission of the return type is quite a different feature. Not to mention, somebody inexperience looking at the code, trying to understand what it does would be very confusing - without knowing the return type of reduce
.
Well said. And this should continue to be the guiding principal of this language. I would also like to put a permanent block on any proposals or changes to the language that's only claim is that it makes code 'clearer'/'more expressive' while also only providing a secondary syntax to something that already exists and functions perfectly well. These are buzz words/phrases with almost no meaning when all we're talking about just creating more and more alternative syntax patterns for the same thing. This is a negative type of expressiveness.
There is no utility in adding another use for ->.
There isn't much utility in most of the syntactic sugar added in the last six months, and I so painfully want to digress from that discussion, but just can't let it go. (à la multiple training closures which was really just an argument to get rid of trailing closures all together, this definitely didn't make things clearer but still passed). Regardless, I think we're all in a losing battle here. The trend in Swift is to diverge from the core principles and create a completely different language.