I like the idea behind this pitch, because my team has found implicit returns from functions confusing.
Some team members try to use implicit return every single time they have a single-line function, while other team members find the syntax confusing unless the function is short enough to fit on a single line anyway. If Swift had special syntax for single-line returns like JavaScript (or C#, Kotlin, and the other languages mentioned upthread), our style guide would recommend using that syntax when it makes sense, and explicit return otherwise (just like our team’s JavaScript linter already enforces).
However, I agree with other commenters that it’s confusing to overload -> for this purpose. @BigSur suggested the C#-style fat arrow => in jest, but I think it’s the perfect choice for a few reasons. (It’s also available in JavaScript.)
Overloading -> makes it impossible to explicitly specify the return type for functions, but not for properties (as @donny_wals pointed out). With => it’s still possible to annotate the type of you want to (or need to, to resolve ambiguity):
// Use the inferred type if you prefer
func someInt() => Int.random(in: 0..<100)
var someInt => Int.random(in: 0..<100)
// Explicitly specify the type if you prefer
func someBool() -> Bool => Bool.random()
var someBool: Bool => Bool.random()
protocol SomeProtocol {
// Not ambiguous because => can’t be used in a protocol
func makeInt() -> Int
}
@GetSwifty suggested the Kotlin-style =. That might work for functions, but it won’t work for properties because it collides with the stored property syntax. And even though it works for functions, it’s still confusing, because it’s not clear that the function body is evaluated every time the function is called, unlike properties that are called just once:
// Computed property, called every time
var sum: Int { reduce(0, +) }
// Function, called every time
func sum() -> Int { reduce(0, +) }
// Stored property, called once
var sum = reduce(0, +)
// Function, called every time (!)
func sum() = reduce(0, +)
=> doesn’t have that same confusion, and it can be used for computed properties:
// Stored property, called once
var sum = reduce(0, +)
// Computed property, called every time
var sum => reduce(0, +)
// Function, called every time
func sum() => reduce(0, +)
@Viranchee raised a good point, that this syntax shouldn’t be limited to getters and not setters in computed properties and subscripts. Thankfully, it doesn’t have to be limited, because assignment returns Void and that’s what set expects:
subscript(key: Key) -> Value {
get => storage[key] ?? fallback
set => storage[key] = newValue
}
-> would also work for set, so this isn’t an advantage for => specifically.