For cases where closure is specifically expected to return clearly defined value (or Void), this pitch might be fine, but for cases where return value is more ambiguous (e.g either void or value), there might be situations where developer accidentally uses non-returning variant of function when developer meant to return value. In those ambiguous situations it’s better to always include ”return” when value returning function is used, so that code is more easily understood
EDIT: My point above is slightly misguided, as closures already allow the shorthand syntax, so this is only about functions.
However, I see closures overall as shorthand (also including the special parameter syntax), and functions as the more fully formed syntax. I think it's good that they are separate, and don't see need for functions getting a shorthand syntax like this.
Yeah, that's my common use case too, and the one I'm most happy about in this proposal. Applying it to regular functions is more of a "sure, I guess it's good to be consistent" thing for me.
Would it make sense to explicitly exclude types Void and Never from this proposal? If feasible, that would simply avoid the edge cases where the intention might be unclear (and would be 100% source compatible).
Limited to only single expression functions, maybe this wouldn't be too confusing. That said, I like the last alternative best, but with a further limitation of just local functions only (does limiting the scope help with type inference?) and with a fat arrow. That would give programmers a real one-liner:
func multiplyByTwoAndThree(a: Int) -> (Int, Int) {
func multiply(b: Int) => a * b
return (multiply(b: 2), multiply(b: 3))
}
I think this looks really great and I'm looking forward to have this in Swift. Since you mentioned Scala in the last paragraph there is something else they allow which I think would be a big benefit for the proposal: have the expression after an = symbol instead of curly brackets.
This would make it much more obvious that this is the value that gets returned and makes it distinguishable from the current syntax.
So I propose to change the syntax from
func functionName(parameter1: Par1, parameter2: Par2) -> Ret {
expressionThatReturnsRet()
}
to
func functionName(parameter1: Par1, parameter2: Par2) -> Ret = expressionThatReturnsRet()
Function bodies with {} would still need the explicit return keyword. This syntax could also be forwarded to other occasions like subscripts or get/set:
var foo: Foo {
get = _foo
set { _foo = newValue }
}
From the top of my head I know that Scala and Kotlin are allowing this (Haskell as well kind of). What do you think?
In the original pitch it's very hard to read what exactly is returning. When you are new to the language you have no Idea what's going to happen here. Especially if you don't have an IDE available.
Excuse me? Can I ask why my proposal of the exact same thing was pushed back so hard especially by @Chris_Lattner3 back then? I appreciate all the work that author has done on this proposal but he missed the historical research on why this was not pushed forward so far.
By this comment this feature was simply put onto the bookshelf for many many years until Swift evolved so much that there is not much to add except convenient sugar:
The same proposal long time ago, before an implementation was required:
To be clear with everyone, I'm not trying to flame here nor do I put a brick in front of this proposal, as I proposed it myself already a few times, but I'm a little bit speechless and as I mentioned above already I appreciate the work from the current author.
Although I like this aesthetically, and for its consistency with other languages, there's an ambiguity hazard here because many introducer keywords in Swift are contextual, including get and set. This is already valid, albeit unlikely:
var get = 0
var foo: Void { get = 0 } // a get only computed property
Ruby allows implicit returns everywhere and I find it to be very confusing so I always am explicit in my returns anyways (coming from C/C++, python, and swift).
I do like the suggested alternate syntax that requires expressions in {} to still use return while declaration = expression can be the "implicit return" expression. This eliminates my confusion of not seeing a return and wondering why something is being returned anyways. There is no doubt about what the = means in my mind.
I think this looks great. The nice part is that the new contexts that this expands skippable return to always have types specified explicitly, so there's much less chance for any kind of ambiguity.
I will say that I hope we can provide good error messaging / fix-its for the case where someone adds an additional line to a function using this feature. Perhaps if the compiler runs into code that doesn't have a required return statement, it can look to see if the final statement in the function body matches the function's type and offer a fix-it.
public func hi() -> Int {
print("entering hi")
17
}
gets the more helpful diagnostic with a fixit
> debug-swift test.swift
test.swift:3:5: warning: integer literal is unused
17
^~
test.swift:3:5: error: missing return in a function expected to return 'Int'; did you mean to return the last expression?
17
^
return
FWIW, I still feel exactly the same way about this, and I find that the "just omit the return" proposal to be super problematic from a clarity perspective.
The func f() -> Int = 42 variant is a significant improve on that clarity issue, but I still don't think it is "worth it" to add complexity to the language for this.