This proposal is dangerous and introduces more potential programmer error and debug hell, makes code harder for humans to reason about (especially if you are unfamiliar with the code), and adds little value to the language.
More Inconsistency
Introducing a 'last expression as return value' is actually creating inconsistency. It is creating a special case for multi-line closures and functions where 'return' is required in all other instances to exit the function except in this special case. It is consistent to say "if it is single-line, you can elide it, if it is not you cannot".
Debug, Code-Evolution Hell*
Readability is not the necessary concern -- using the word 'readability' makes it sounds like a 'this is just the way I like it' argument. It's actually safety, correctness, explicitness, and prevention of unexpected behavior concern.
The reason that multi-line expressions need an explicit return is due to debugging and code safety. When we have these discussions, we give these extremely trivial examples that are less than 10 lines each where the security issue isn't apparent. These examples are super easy to reason about so it gives the appearance that a 'readability' concern is just a lack of intelligence on the part of the say-sayers. However, code does not typically look like this. We are often writing functions that are hundreds of lines long, with commented code sprinkled about. Something that is rarely possible in single line functions/closures where the current exception exists and where it should stay.
A library of String processors is often going to have loads of @discardableResult
functions which if placed at the end of a function that also returns the same type will be a valid return type but not necessarily the intended return value.
Imagine writing a large function that returns a particular value and you have elided return
. Imagine writing additional code to that function, which later returns the a different value. Going back to your function you might not even notice or remember that a particular line of code was the official return value even if it was the last line and you were adding more to it. The signal that the function even returned is now gone.
Now imagine writing a function that previously did NOT return a value, and you now give it a return type. The code could easily compile due to the last line being a valid return type -- again not the intended value.
Even worse, now the proposal suggest that eliding 'return' to make the following example more fun to write, but actually this is also debug hell because now an if
statement that is your last line of code could be providing your return value neither of which TRULY come from the last line. Without knowing it, I could be getting a return value from DEEP inside of a if
statement. The example below, btw is not typical of a function, a function is often VERY large, so spare the 'oh well I can clearly see where the return is happening.'
static func randomOnHemisphere(with normal: Vec3) -> Vec3 {
let onUnitSphere: Vec3 = .randomUnitVector
if onUnitSphere • normal > 0 {
onUnitSphere <---- this could be the value returned
} else {
-onUnitSphere <----- this could be the value returned!
}
}
Removing explicitness is not just a 'reading' issue, it is a very real security concern. It allows the compiler to do guess your intentions and attempt to disambiguates situations that should otherwise be explicit -- except we added an exception that if it is on the last line then we can just return that.
A lot of time, we ignore these concerns with 'well the IDE could help us here… it will tell us what is happening'… Some of my projects compile exclusively in the terminal, there is no IDE. I use a text editor often to debug in certain situations.
No Real Value
We are not adding usability value to Swift by eliding 'return' on the last line of a function/closure. It is at most saving 7 characters that brings you explicitness and does not introduce unexpected behavior in the process of actually editing and evolving your code.
Furthermore within if
expressions, we should introduce a keyword for yielding/returning the value when there are multi lines (I actually wish this was required for single line too)