# SE-0255: Implicit Returns from Single-Expression Functions

**URL:** <https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544>\
**Category:** Proposal Reviews\
**Created:** [April 2, 2019, 8:26pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544 "2019-04-02T20:26:32Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [April 4, 2019, 7:10pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/63 "2019-04-04T19:10:19Z")

</div>

Really, both of these forms are motivated by legitimate reasoning, so neither of them is arbitrary. But I disagree that my hypothetical rule is _more_ arbitrary. The refactoring required to transform

```swift
numbers.map { $0*2 }

```

into

```swift
let double = { $0*2 }
numbers.map(double)

```

is of a conceptually different sort than going from

```swift
let double = { $0*2 }

```

to

```swift
func double(_ x: Double) -> Double { return x * 2 }

```

In any case, the hypothetical adjustment I presented is fairly off-topic for extended discussion on the proposal review thread.

Regardless of how I think it _should_ be, though, the current state of affairs doesn't strike me as wildly arbitrary either. The step from closure to `func` is essentially a transformation of "let me be very explicit about several things that were implicit before," which applies to argument names, argument types, return types, and actually specifying `return`. To me, there's nothing wrong with that.

---

<div class="post-metadata">

**Author:** ![phlebotinum](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/phlebotinum/32/1515_2.png) [@phlebotinum](https://forums.swift.org/u/phlebotinum)\
**Post date:** [April 4, 2019, 7:17pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/64 "2019-04-04T19:17:08Z")

</div>

+1 for consistency

---

<div class="post-metadata">

**Author:** ![Preston\_Sumner](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/preston_sumner/32/1640_2.png) [@Preston\_Sumner](https://forums.swift.org/u/Preston_Sumner)\
**Post date:** [April 4, 2019, 9:29pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/65 "2019-04-04T21:29:48Z")

</div>

Consistency isn't even the most convincing argument to me. I simply think it's intuitive but non-essential shorthand that will always be desired by users writing compact one-line functions and getters.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 4, 2019, 11:27pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/66 "2019-04-04T23:27:16Z")

</div>

> [@ben-cohen](#):
>
> At what seems like an arbitrary point in this otherwise smooth transition up the ladder of expressivity, you are forced to introduce a `return` . Why? Seems arbitrary to me. Not a big deal, maybe, but this is somewhere the consistency would make the language better IMO,

Well, at the point where one _chooses_ to use `func`, one is required also to use `return`. In other words, it isn’t an arbitrary point along the continuum, divorced from all other syntactic changes, that the requirement for `return` kicks in. It isn’t any more ‘consistent’ to make it optional there than to articulate a simple rule: where these is `func`, there must be `return`.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [April 4, 2019, 11:35pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/67 "2019-04-04T23:35:28Z")

</div>

> [@xwu](#):
>
> It isn’t any more ‘consistent’ to make it optional there than to articulate a simple rule: where these is `func` , there must be `return` .

The rule stated that way is actually: where there is `func` **or** more than a single expression there must be `return`. That is clearly a more complex rule than: where there is more than a single expression there must be `return`. The reduction in complexity of the rule makes the language simpler overall. The difference is admittedly marginal, but it would be quite meaningful when measured by the experience of Swift programmers (many of us) who upon learning the closure shorthand immediately thought it would make sense to allow implicit return anywhere there is a single expression (and therefore thought the limitation was somewhat arbitrary).

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 4, 2019, 11:42pm UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/68 "2019-04-04T23:42:52Z")

</div>

> [@anandabits](#):
>
> The rule stated that way is actually: where there is `func` **or** more than a single expression there must be `return` . That is clearly a more complex rule than: where there is more than a single expression there must be `return` . The reduction in complexity of the rule makes the language simpler overall.

No, the statement is correct: where this is `func`, there must be `return`. This does not imply that where there is `return`, there must be `func`.

You missed the point of my reply, which is that it is not at an arbitrary point in the continuum outlined by Ben that `return` is required, but precisely where there is `func`.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [April 5, 2019, 12:20am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/69 "2019-04-05T00:20:13Z")

</div>

> [@xwu](#):
>
> This does not imply that where there is `return` , there must be `func` .

I didn’t say that it does. I just pointed out the complete current rule for when `return` must be present.

> [@xwu](#):
>
> You missed the point of my reply, which is that it is not at an arbitrary point in the continuum outlined by Ben that `return` is required, but precisely where there is `func` .

I understand that is your point. I was making a further point that while it may not be completely arbitrary in that sense it does feel rather arbitrary (at least to many of us) in the context of the complete rule for where `return` is currently required.

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [April 5, 2019, 12:35am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/70 "2019-04-05T00:35:14Z")

</div>

> [@xwu](#):
>
> where this is `func` , there must be `return` .

That is _when_. It is not _why_. It is the lack of a _why_ that is arbitrary. The rule for when the change occurs can be clear and well-defined, but still arbitrary.

---

<div class="post-metadata">

**Author:** ![Lily\_Ballard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lily_ballard/32/5050_2.png) [@Lily\_Ballard](https://forums.swift.org/u/Lily_Ballard)\
**Post date:** [April 5, 2019, 12:51am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/71 "2019-04-05T00:51:46Z")

</div>

> [@ben-cohen](#):
>
> That is _when_ . It is not _why_ . It is the lack of a _why_ that is arbitrary. The rule for when the change occurs can be clear and well-defined, but still arbitrary.

You could say the same thing about how when there's a `func` there's also a fully-written explicit type signature.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [April 5, 2019, 12:59am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/72 "2019-04-05T00:59:50Z")

</div>

> [@Lily\_Ballard](#):
>
> You could say the same thing about how when there's a `func` there's also a fully-written explicit type signature.

FWIW, [as I pointed out upthread](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/24) if we consider the assignment-like sugar instead of the currently proposed sugar then this also starts to feel arbitrary. Why can the type of a stored property be inferred but not the type of a get-only computed property or subscript or the return type of a single-expression function _when these constructs are limited to single expression bodies_?

The primary principle behind our inference boundaries as I understand it is that we don't infer types across statements. That principle is not relevant for single-expression bodies.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [April 5, 2019, 1:03am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/73 "2019-04-05T01:03:39Z")

</div>

Type inference for non-local declarations (those outside of function bodies) can have a significant impact on compilation time, so I'd rather not mess with that. I'm also on the ideological side that defining your interfaces clearly is a good thing, even when you're just talking about the interfaces within your own module, but that's a fuzzier argument.

(Rust is also in the "we'll infer a lot of types for you, but not in your declarations, except lifetimes" camp. Haskell is on the other side.)

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [April 5, 2019, 1:09am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/74 "2019-04-05T01:09:13Z")

</div>

> [@Lily\_Ballard](#):
>
> You could say the same thing about how when there's a `func` there's also a fully-written explicit type signature.

I can think of a few good reasons for this that I would happily reel off if someone suggested functions types could be inferred (functions are contracts, you'd need to infer the types from the body multiple times while building which is an argument against inferred stored property types, etc).

What I am looking for is similar reasons for the return elision being a no-go for functions in particular.

To put my review manager hat back on: reviews on evolution are not ballots. It is not especially useful to say you are for or against something, that you like or dislike something, other than in simple cases where all comments are in favor. It is the rationale that is important. The core team reviews the discussion looking for reasons the proposal should be accepted, rejected, or modified.

So what is needed here if the core team is to (for example) decide that return elision should be accepted for properties but not for functions is a clear reason why it would be harmful to allow it for functions in particular, while being good to allow it for properties.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [April 5, 2019, 1:23am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/75 "2019-04-05T01:23:44Z")

</div>

> [@jrose](#):
>
> Type inference for non-local declarations (those outside of function bodies) can have a significant impact on compilation time, so I'd rather not mess with that. I'm also on the ideological side that defining your interfaces clearly is a good thing, even when you're just talking about the interfaces within your own module, but that's a fuzzier argument.
> 
> (Rust is also in the "we'll infer a lot of types for you, but not in your declarations, except lifetimes" camp. Haskell is on the other side.)

I’m not arguing for or against this, just trying to point out how things look from the programmer’s perspective. There may well be compilation time issues that would exist for single-expression bodies that don’t exist for stored properties. It isn’t clear to me why that would be the case but I’m definitely not an expert in this area!

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [April 5, 2019, 2:26am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/76 "2019-04-05T02:26:24Z")

</div>

Unless the return type is `Void`. Swift allows elision in many scenarios, when it makes sense. And that's without getting into type inference.

---

<div class="post-metadata">

**Author:** ![Lily\_Ballard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lily_ballard/32/5050_2.png) [@Lily\_Ballard](https://forums.swift.org/u/Lily_Ballard)\
**Post date:** [April 5, 2019, 3:06am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/77 "2019-04-05T03:06:09Z")

</div>

> [@ben-cohen](#):
>
> So what is needed here if the core team is to (for example) decide that return elision should be accepted for properties but not for functions is a clear reason why it would be harmful to allow it for functions in particular, while being good to allow it for properties.

Return elision in functions only makes sense to me if we have full-blown statements-as-expressions like Rust. Functions are named callable chunks of code and there's nothing special about the last statement in a function that warrants it being given special behavior.

Also, unlike property getters and closures, having a `Void` return type is quite common for a function. If I look at a function body without its type signature, I can tell what the function's return type is... unless we have return elision. Then I can't. Which could also lead to more confusing error messages if the function's body doesn't match its return type.

There's also the stylistic angle to consider. Single-expression closures are frequently written on a single line, such as `{ $0 + $1 }`. That's the core argument in favor of return elision. Property getters are also frequently written on a single line, such as `get { return label.font }`. This feels very much like a closure, and even looks like I'm passing a closure to a function/keyword named `get`. But functions are typically never written on a single line. While you certainly could write `func foo(x: Int) -> Int { return x + 1 }` without any line breaks, stylistically speaking that would be quite unusual (anecdotally, I've never worked in a codebase that didn't put a new line after the opening brace regardless of function brevity). Return elision for functions really only makes sense if we expect people to not put a newline after the brace, and we don't.

---

<div class="post-metadata">

**Author:** ![Lily\_Ballard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lily_ballard/32/5050_2.png) [@Lily\_Ballard](https://forums.swift.org/u/Lily_Ballard)\
**Post date:** [April 5, 2019, 3:07am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/78 "2019-04-05T03:07:37Z")

</div>

Oh I also forgot to mention, single-line closures and property getters are extremely common. Single-line functions are fairly rare, so having return elision show up there is likely to be more confusing than helpful.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [April 5, 2019, 3:10am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/79 "2019-04-05T03:10:16Z")

</div>

> [@Lily\_Ballard](#):
>
> Functions are named callable chunks of code and there's nothing special about the last statement in a function that warrants it being given special behavior.

Whoa, hang on. No one is proposing last-statement return elision.

> [@Lily\_Ballard](#):
>
> If I look at a function body without its type signature, I can tell what the function's return type is... unless we have return elision.

We already don't have that:

```swift
func computeImportantConstantForGraphicsStuff(…) -> ???? {
  guard self.isShowingTheExtraStuff else {
    return 0 // …actually a CGFloat
  }
  // …
}

func fetchAllItems(…) -> ???? {
  guard self.isConnected else {
    return [] // Array of what?
  }
  // …
}

func performCachedOperation(…) -> ???? {
  guard !self.hasDoneTheCachedThing else {
    return .okay // A status of some kind, but which one?
  }
  // …
}

```

---

<div class="post-metadata">

**Author:** ![Lily\_Ballard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lily_ballard/32/5050_2.png) [@Lily\_Ballard](https://forums.swift.org/u/Lily_Ballard)\
**Post date:** [April 5, 2019, 3:33am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/80 "2019-04-05T03:33:52Z")

</div>

> [@jrose](#):
>
> Whoa, hang on. No one is proposing last-statement return elision.

True, but I don't consider the following two functions to be different in any meaningful sense:

```swift
func foo() -> Int {
    let x = 5
    return x
}
func bar() -> Int {
    return 5
}

```

so why should I be able to elide the `return` in the second but not the first?

Of course, closures also have the single-expression rule, and to be honest, I'd be in favor of allowing returns to be elided in multi-line closures as long as the closure's type signature can still be unambiguously determined (either written explicitly, or inferrable from usage without looking at the closure body), but I'm not pushing for that because it would likely lead to more confusing errors down the road ("why can I elide `return` in this closure but not that one?").

> [@jrose](#):
>
> We already don't have that:

True, but you can at least determine the shape of what's being returned in each of those cases: A number (or at least, expressible by numeric literal), an array (or expressible by array literal), and a type that has a static member `.okay`. Whereas with return elision, if you don't look at the function's type signature you can't even tell whether the function is returning a value at all.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 5, 2019, 3:53am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/81 "2019-04-05T03:53:22Z")

</div>

> [@ben-cohen](#):
>
> I can think of a few good reasons for this that I would happily reel off if someone suggested functions types could be inferred (functions are contracts, you'd need to infer the types from the body multiple times while building which is an argument against inferred stored property types, etc).
> 
> What I am looking for is similar reasons for the return elision being a no-go for functions in particular.

> [@Lily\_Ballard](#):
>
> Return elision in functions only makes sense to me if we have full-blown statements-as-expressions like Rust.

> [@anandabits](#):
>
> The primary principle behind our inference boundaries as I understand it is that we don't infer types across statements. That principle is not relevant for single-expression bodies.

> [@Lily\_Ballard](#):
>
> Single-expression closures are frequently written on a single line, such as `{ $0 + $1 }` . That's the core argument in favor of return elision. Property getters are also frequently written on a single line, such as `get { return label.font }` . This feels very much like a closure, and even looks like I'm passing a closure to a function/keyword named `get` . But functions are typically never written on a single line.

Et voilà: I think we've discovered the principle at work here:

It's not so much the _stylistic_ significance of how most users use one line versus multiple lines, but that fundamentally anything spelled with `func` is always treated as a collection of statements.

Short closures are given a privileged syntax such that they can be spelled like an expression surrounded by braces for reasons already given; this naturally lends itself to a continuum where one extreme is actually the single-expression autoclosure, **which is literally spelled _as an expression_**.

Getters for computed properties are thought of similarly by many users (as evidenced here), perhaps because the RHS of a _non_-computed property **_literally is_ an expression**.

But users simply don't treat functions in that way. In part, it is because the ceremony of writing out a full declaration naturally pushes users to set the contents apart. I would posit, though, in part it is because there is no close counterpart to functions where you have a function declaration followed by an actual expression.

If we had full-blown statements-as-expressions, this would not be an issue.

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [April 5, 2019, 4:27am UTC](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544/82 "2019-04-05T04:27:16Z")

</div>

> [@Lily\_Ballard](#):
>
> While you certainly could write `func foo(x: Int) -> Int { return x + 1 }` without any line breaks, stylistically speaking that would be quite unusual

I do this.

> [@Lily\_Ballard](#):
>
> True, but you can at least determine the shape of what's being returned in each of those cases: A number (or at least, expressible by numeric literal), an array (or expressible by array literal), and a type that has a static member `.okay` .

I have no idea why this is a consideration at all (I've never heard of “guessing the return type of a function body without looking at the signature” being a common activity, parlour game, or Swift design goal) but this isn't generally true either. The return value can be, and often is, the return value of another function.

[Previous page](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544.md?page=3)

[Next page](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544.md?page=5)
