[Proposal] function "return" optional keyword.


(Craig Cruden) #1

When writing short functional code in a function it would be nice if the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.


(Matthew Johnson) #2

Not sure if I like this or not, but if we do adopt it I think it should be consistent with the rule for closures. Following the current rule for closures, this would only apply to single expression functions. I think I could support that.

···

On Dec 19, 2015, at 9:53 AM, Dennis Lysenko via swift-evolution <swift-evolution@swift.org> wrote:

This is very nice for writing lazy var definitions and single-line computed properties as well. +1 from me.

On Sat, Dec 19, 2015, 8:30 AM Craig Cruden via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

When writing short functional code in a function it would be nice if the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Step C) #3

There was discussion of implicit returns on the forums a while back. Will try to find the link later. The Swift team chose explicit returns for better code clarity. I still think this was the right call, even though implicit returns are certainly attractive when writing code.

···

On Dec 19, 2015, at 12:45 PM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

Afaik the concept is quite common when "everything is an expression", which can be a nice feature of a language:
It saves keystrokes, and allows constructs like
let value = switch key {…}
But as the let syntax was changed to work with delayed assignment, one major use case is solved in a different way, and I doubt that it fits into the Swift roadmap.
Imho clarity is reduced, and it can look a little bit odd to end a function with a line like
value

On the other hand, nobody would be forced to skip the "return", and I guess it wouldn't be a complicated change in the compiler… so if you want to continue working on the proposal, I would evaluate how this change could be reflected in the docs.

Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dennis Lysenko) #4

This is very nice for writing lazy var definitions and single-line computed
properties as well. +1 from me.

···

On Sat, Dec 19, 2015, 8:30 AM Craig Cruden via swift-evolution < swift-evolution@swift.org> wrote:

When writing short functional code in a function it would be nice if the
return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Step C) #5

The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)


(Jens Persson) #6

+1

···

On Sat, Dec 19, 2015 at 2:30 PM, Craig Cruden via swift-evolution < swift-evolution@swift.org> wrote:

When writing short functional code in a function it would be nice if the
return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
bitCycle AB | Smedjegatan 12 | 742 32 Östhammar | Sweden
http://www.bitcycle.com/
Phone: +46-73-753 24 62
E-mail: jens@bitcycle.com


(Tino) #7

Afaik the concept is quite common when "everything is an expression", which can be a nice feature of a language:
It saves keystrokes, and allows constructs like
let value = switch key {…}
But as the let syntax was changed to work with delayed assignment, one major use case is solved in a different way, and I doubt that it fits into the Swift roadmap.
Imho clarity is reduced, and it can look a little bit odd to end a function with a line like
value

On the other hand, nobody would be forced to skip the "return", and I guess it wouldn't be a complicated change in the compiler… so if you want to continue working on the proposal, I would evaluate how this change could be reflected in the docs.

Tino


(Lily Ballard) #8

If Swift ever changes to be Rust-like and have every statement actually be an expression with a non-void type (I believe this was discussed in the thread about replacing ?:), then your proposed behavior is already an implicit part of that change.

But barring a large change like that, I'm against dropping the `return`
here, as it's inconsistent with the rest of the language. The only
construct today that lets you drop the return is a one-line closure, but
that's already something that looks like an expression (`foo.map({ $0.x
})` looks perfectly fine; `foo.map({ return $0.x })` is just unnecessary
syntax). But the last statement of a function isn't an expression, it's
a statement.

-Kevin Ballard

···

On Sat, Dec 19, 2015, at 05:30 AM, Craig Cruden via swift-evolution wrote:

When writing short functional code in a function it would be nice if
the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) { (arg2,
arg1) }

The keyword return would still be there for breaking out of a
function.

_________________________________________________
swift-evolution mailing list swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dennis Lysenko) #9

Yes, this would be strange in multiline functions with different execution
paths. It works well in Ruby because function return types aren't
annotated, so the final expression is always a valid return value. In
swift, I think it would have too much design overhead to figure out how to
reconcile it with explicit return types, to be worth it with multiline
functions. However, it would be great to have implicit return in single
line closures with named parameters and single line functions.

···

On Sat, Dec 19, 2015, 2:28 PM Step C via swift-evolution < swift-evolution@swift.org> wrote:

There was discussion of implicit returns on the forums a while back. Will
try to find the link later. The Swift team chose explicit returns for
better code clarity. I still think this was the right call, even though
implicit returns are certainly attractive when writing code.

> On Dec 19, 2015, at 12:45 PM, Tino Heth via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Afaik the concept is quite common when "everything is an expression",
which can be a nice feature of a language:
> It saves keystrokes, and allows constructs like
> let value = switch key {…}
> But as the let syntax was changed to work with delayed assignment, one
major use case is solved in a different way, and I doubt that it fits into
the Swift roadmap.
> Imho clarity is reduced, and it can look a little bit odd to end a
function with a line like
> value
>
> On the other hand, nobody would be forced to skip the "return", and I
guess it wouldn't be a complicated change in the compiler… so if you want
to continue working on the proposal, I would evaluate how this change could
be reflected in the docs.
>
> Tino
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #10

I'm not going to go as far as a definitive +1, but I've definitely wanted this for var and subscript getters. If it were limited to single-expression functions, I don't see much harm. The only time there'd be a problem is if the return types matched and you were going to have another statement instead.

It feels weird for anything imperative, but I think the whole point is that there are plenty of functions which do absolutely no imperative work. I personally wouldn't want people to start using it for forwarding imperative things, though.

func sendHTTPRequest() -> Result {
  sendHTTPRequestImpl(destinationURL, body)
}

Jordan

···

On Dec 19, 2015, at 5:30 , Craig Cruden via swift-evolution <swift-evolution@swift.org> wrote:

When writing short functional code in a function it would be nice if the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Félix Cloutier) #11

Just food for thought: C# has a special syntax, inspired by its own lambda syntax, for single-expression functions:

// lambda syntax
param => param + 4

// single-expression method syntax
int AddFour(int param) => param + 4;

Swift's syntax for declaring functions and lambdas are harder to link like that though.

Félix

···

Le 19 déc. 2015 à 23:26:49, Jordan Rose via swift-evolution <swift-evolution@swift.org> a écrit :

I'm not going to go as far as a definitive +1, but I've definitely wanted this for var and subscript getters. If it were limited to single-expression functions, I don't see much harm. The only time there'd be a problem is if the return types matched and you were going to have another statement instead.

It feels weird for anything imperative, but I think the whole point is that there are plenty of functions which do absolutely no imperative work. I personally wouldn't want people to start using it for forwarding imperative things, though.

func sendHTTPRequest() -> Result {
  sendHTTPRequestImpl(destinationURL, body)
}

Jordan

On Dec 19, 2015, at 5:30 , Craig Cruden via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

When writing short functional code in a function it would be nice if the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Craig Cruden) #12

I looked at the discussion and it looked like they were discussion two things combined.
   - inferred return type (on function signature)
   - and omitting return on the return.

I agree with Chris on the fact that the function should have the type of return specified on the signature and not inferred since it is useful for API documentation to know that ahead of time on a strongly typed language.

What is not necessary is actually forcing people to type return “x” on the last line - since “return” is rather redundant and clutter for those people of a functional programming paradigm point of view.

···

On 2015-12-20, at 4:15:15, Stephen Christopher via swift-evolution <swift-evolution@swift.org> wrote:

The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Andrew Bennett) #13

+1 for consistency with closures

···

On Sun, Dec 20, 2015 at 8:15 AM, Stephen Christopher via swift-evolution < swift-evolution@swift.org> wrote:

The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Andrew Bennett) #14

Great points Kevin, that's pretty much my thinking as well. If we're
heading towards everything being an expression then it'll happen, perhaps
that change shouldn't be incremental as you've suggested, I'm not sure.

The only time I've found I've naturally wanted to do this is with things
like property definitions:

var twiceSomething: Int { self.something * 2 }

···

On Sun, Dec 20, 2015 at 1:55 PM, Kevin Ballard via swift-evolution < swift-evolution@swift.org> wrote:

If Swift ever changes to be Rust-like and have every statement actually be
an expression with a non-void type (I believe this was discussed in the
thread about replacing ?:), then your proposed behavior is already an
implicit part of that change.

But barring a large change like that, I'm against dropping the `return`
here, as it's inconsistent with the rest of the language. The only
construct today that lets you drop the return is a one-line closure, but
that's already something that looks like an expression (`foo.map({ $0.x })`
looks perfectly fine; `foo.map({ return $0.x })` is just unnecessary
syntax). But the last statement of a function isn't an expression, it's a
statement.

-Kevin Ballard

On Sat, Dec 19, 2015, at 05:30 AM, Craig Cruden via swift-evolution wrote:

When writing short functional code in a function it would be nice if the
return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

*_______________________________________________*
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Radek Pietruszewski) #15

I honestly don’t have a problem with having to say `return` inside functions. That’s not necessarily a -1, but I’m reluctant to say +1 when _even I_ don’t really have the problem with extra verbosity.

*However*, as others pointed out, having to type `return` is a bit tiring in the context of a computer property’s “get”:

var twiceSomething: Int { self.something * 2 }

— Radek

···

On 19 Dec 2015, at 14:30, Craig Cruden via swift-evolution <swift-evolution@swift.org> wrote:

When writing short functional code in a function it would be nice if the return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Owens II) #16

-1 for me. Closures gain a special syntax because of their use case, specifically inlining locally. Functions don’t get that.

···

On Dec 19, 2015, at 4:44 PM, Andrew Bennett via swift-evolution <swift-evolution@swift.org> wrote:

+1 for consistency with closures

On Sun, Dec 20, 2015 at 8:15 AM, Stephen Christopher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #17

Is there a reason that any final non-void statement in a closure or function shouldn't automagically be an optional return? (And automagically warn_unused_result...?)

···

On Dec 19, 2015, at 5:44 PM, Andrew Bennett via swift-evolution <swift-evolution@swift.org> wrote:

+1 for consistency with closures

On Sun, Dec 20, 2015 at 8:15 AM, Stephen Christopher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jacob Bandes-Storch) #18

In this scenario, should calling a warn_unused_result function as the last
statement in a closure/function count as "using" its result (i.e.
implicitly returning it)?

Jacob

···

On Sat, Dec 19, 2015 at 4:51 PM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

Is there a reason that any final non-void statement in a closure or
function shouldn't automagically be an optional return? (And automagically
warn_unused_result...?)

On Dec 19, 2015, at 5:44 PM, Andrew Bennett via swift-evolution < > swift-evolution@swift.org> wrote:

+1 for consistency with closures

On Sun, Dec 20, 2015 at 8:15 AM, Stephen Christopher via swift-evolution < > swift-evolution@swift.org> wrote:

The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(ilya) #19

-1 on inferred return type and omitting return with func

Both features are actually available in the language as-is, just not with
the func keyword:

let someInferredFunction = { _ in 5} // () -> Int

When teaching Swift we actually teach func + return keywords together, they
make it easy to see all possible return paths from a function.

And we recommend using func instead of a closure when there is a multiline
body with control statements. Having implicit return in that case hurts
readability. For example, out of three possible return points within this
function only one is not marked with return:

func f(input: Int) -> Int {
    if input > 10 {
        return 10
    }
    if input < 0 {
        return 0
    }
    input
}

+1 on omitting return from var {} declaration, those methods look like
closures and will often be one-liners.

···

On Sun, Dec 20, 2015 at 5:29 AM, Craig Cruden via swift-evolution < swift-evolution@swift.org> wrote:

I looked at the discussion and it looked like they were discussion two
things combined.
   - inferred return type (on function signature)
   - and omitting return on the return.

I agree with Chris on the fact that the function should have the type of
return specified on the signature and not inferred since it is useful for
API documentation to know that ahead of time on a strongly typed language.

What is not necessary is actually forcing people to type return “x” on the
last line - since “return” is rather redundant and clutter for those people
of a functional programming paradigm point of view.

On 2015-12-20, at 4:15:15, Stephen Christopher via swift-evolution < > swift-evolution@swift.org> wrote:

The discussion I was remembering, comment courtesy of Chris:
https://devforums.apple.com/message/1014317#1014317

(linked from https://devforums.apple.com/thread/255242)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(ilya) #20

For those simple computed var cases I wonder if we could use a simpler
definition, inferring the type:

var twiceSomething => something * 2

On the other hand, it's better to specify types for names that can be
visible outside of current scope explicitly. So may be the getter declared
via this syntax should always be private.

···

On Sun, Dec 20, 2015 at 23:29 Radosław Pietruszewski < swift-evolution@swift.org> wrote:

I honestly don’t have a problem with having to say `return` inside
functions. That’s not necessarily a -1, but I’m reluctant to say +1 when
_even I_ don’t really have the problem with extra verbosity.

*However*, as others pointed out, having to type `return` is a bit tiring
in the context of a computer property’s “get”:

var twiceSomething: Int { self.something * 2 }

— Radek

On 19 Dec 2015, at 14:30, Craig Cruden via swift-evolution < > swift-evolution@swift.org> wrote:

When writing short functional code in a function it would be nice if the
return keyword were an optional keyword.

Just return the last evaluated expression.

i.e.

    func flipFunc<T, U>(arg1: T, arg2: U) -> (U, T) {
        (arg2, arg1)
    }

The keyword return would still be there for breaking out of a function.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution