Replace named returns with `out` parameters?


(Anton Zhilin) #1

Some people on the list wondered, why we have moved from tuples in function
parameters, but multiple returns are still implemented using tuples? The
following code still compiles:

func position() -> (x: Int, y: Int) {
    return (x: 0, y: 0)
}
let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s
pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters *and* make
them the default for multiple returns for Swift 4. The syntax would look
like:

func position(x: out Int, y: out Int) {
    x = 0
    y = 0
}
var y
position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment,
including wildcard pattern and tuple destructuring pattern.


(Micah Hainline) #2

You haven't really explained what problem this solves, and it would have to be a pretty big one to justify such a change.

I'm -1 on this, until a compelling argument is made. This feels like just liking the syntax of another language and wanting it in Swift.

···

On Dec 28, 2016, at 5:09 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:

Some people on the list wondered, why we have moved from tuples in function parameters, but multiple returns are still implemented using tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {
    return (x: 0, y: 0)
}

let (y, x) = position()
(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters and make them the default for multiple returns for Swift 4. The syntax would look like:

func position(x: out Int, y: out Int) {
    x = 0
    y = 0
}

var y
position(x: let x, y: y)
out arguments can be any patterns allowed on the left side of assignment, including wildcard pattern and tuple destructuring pattern.

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


(Andrew Arnopoulos) #3

Adrian,

I'm not entirely sure I understand. Are you looking for a way to pass parameters by reference? Because there is a way to do that with the inout keyword. If not would you mind providing a different example to elaborate? Again, I think I may be missing your point.

-Andrew

···

On Dec 28, 2016, at 4:09 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:

compiles:


(thislooksfun) #4

Accidentally sent this offlist (why no 'reply to' header?)

-thislooksfun (tlf)

···

On Dec 28, 2016, at 9:52 AM, thislooksfun <thislooksfun@repbot.org> wrote:

This already basically exists in the form `inout`
// Define the function
func position(x: inout Int, y: inout Int) {
    x = 0
    y = 0
}

// Create the variables you want to assign (they do have to be initialized beforehand)
var x = 0, y = 0
// And call it! Remember to prefix with & when using a primitive type (not 100% sure what kinds you don't need to specify that for, but the compiler will tell you).
position(x: &x, y: &y)
There is no way to define a variable from the value passed to an `inout` parameter (it does need to go 'in' as well, after all), but other than that it seems to be what you're asking for.

-thislooksfun (tlf)

On Dec 28, 2016, at 5:09 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Some people on the list wondered, why we have moved from tuples in function parameters, but multiple returns are still implemented using tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {
    return (x: 0, y: 0)
}

let (y, x) = position()
(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters and make them the default for multiple returns for Swift 4. The syntax would look like:

func position(x: out Int, y: out Int) {
    x = 0
    y = 0
}

var y
position(x: let x, y: y)
out arguments can be any patterns allowed on the left side of assignment, including wildcard pattern and tuple destructuring pattern.

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


(Daniel Leping) #5

-1 here. What's wrong with tuples? Don't kill functional approach

···

On Wed, 28 Dec 2016 at 19:35 Micah Hainline via swift-evolution < swift-evolution@swift.org> wrote:

You haven't really explained what problem this solves, and it would have
to be a pretty big one to justify such a change.

I'm -1 on this, until a compelling argument is made. This feels like just
liking the syntax of another language and wanting it in Swift.

On Dec 28, 2016, at 5:09 AM, Anton Zhilin via swift-evolution < > swift-evolution@swift.org> wrote:

Some people on the list wondered, why we have moved from tuples in
function parameters, but multiple returns are still implemented using
tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {

    return (x: 0, y: 0)

}

let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s
pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters *and*
make them the default for multiple returns for Swift 4. The syntax would
look like:

func position(x: out Int, y: out Int) {

    x = 0

    y = 0

}

var y

position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment,
including wildcard pattern and tuple destructuring pattern.

_______________________________________________
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


(Tony Allevato) #6

–1. I'm not sure there's a reason to draw a line from
removal-of-tuple-splat to removal-of-tuple-returns, other than the idea
that they both involve tuples. In a lot of languages, purely-"out"
parameters are a workaround for the fact that the language wasn't designed
to allow functions to return multiple values easily. Since Swift does allow
this, eliminating and adding "out" params is a step *backward*, not a step
forward.

"Inout" parameters at least serve an important role with respect to
in-place mutability. "Out"-only parameters don't seem like something that
would have much value in Swift.

The syntactic distinction between inputs and outputs in Swift's function
syntax is important to readability—I find the example given with "out"
params to be considerably harder to parse mentally than the version that
returns a tuple. From the point of view of making the language easy for
newcomers to learn... replacing tuple returns with "out" parameters would
be extremely harmful.

···

On Wed, Dec 28, 2016 at 3:10 AM Anton Zhilin via swift-evolution < swift-evolution@swift.org> wrote:

Some people on the list wondered, why we have moved from tuples in
function parameters, but multiple returns are still implemented using
tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {
    return (x: 0, y: 0)
}
let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s
pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters *and*
make them the default for multiple returns for Swift 4. The syntax would
look like:

func position(x: out Int, y: out Int) {
    x = 0
    y = 0
}
var y
position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment,
including wildcard pattern and tuple destructuring pattern.

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


(Dominik Pich) #7

Totally against out params. Returning tuples is way more logical & understandable

BR
Dominik

Web: https://pich.info
Twitter: @DaijDjan
Facebook: Dominik.Pich

···

On 28 Dec 2016, at 15:06, Daniel Leping via swift-evolution <swift-evolution@swift.org> wrote:

-1 here. What's wrong with tuples? Don't kill functional approach

On Wed, 28 Dec 2016 at 19:35 Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
You haven't really explained what problem this solves, and it would have to be a pretty big one to justify such a change.

I'm -1 on this, until a compelling argument is made. This feels like just liking the syntax of another language and wanting it in Swift.

On Dec 28, 2016, at 5:09 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Some people on the list wondered, why we have moved from tuples in function parameters, but multiple returns are still implemented using tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {

    return (x: 0, y: 0)

}

let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters and make them the default for multiple returns for Swift 4. The syntax would look like:

func position(x: out Int, y: out Int) {

    x = 0

    y = 0

}

var y

position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment, including wildcard pattern and tuple destructuring pattern.

_______________________________________________
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 <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


(Anton Zhilin) #8

Ok, then –1 from me as well. I didn’t really want to push this feature.
At least now we have some evidence that people find labeled tuples more
convenient and would prefer them to in parameters.

I'm not entirely sure I understand. Are you looking for a way to pass

parameters by reference? Because there is a way to do that with the inout
keyword. If not would you mind providing a different example to elaborate?
Again, I think I may be missing your point.

The difference here would be declaration of the result variable right at
function call. It would be initialized inside the function.

···

2016-12-28 20:42 GMT+03:00 Andrew Arnopoulos <andrewarnopoulos@gmail.com>:


(Lily Ballard) #9

I know you've already decided against this, but I think it deserves an
explanation for why the two are different.

Tuples in function parameters was basically a special case to the type
system. The function type was effectively modeled as taking one argument
which was a tuple, and a function of multiple arguments just had a multi-
element tuple. But this wasn't actually true. For one thing, you could
have a single named argument, but you cannot have a 1-element tuple
(named or no), which means the function argument isn't _really_ a tuple.
For another, this caused weird behavior when invoking functions with a
single tuple element. I don't remember the specifics anymore (I'm not
sure I ever truly understood the rules around this), but in some cases
you could pass a single tuple to a function expecting multiple
arguments, but in other cases you couldn't.

So ultimately, getting rid of the notion that a function's arguments is
a tuple was actually a simplification to the type system and to the
internals, and made the rules a lot more straightforward.

Now contrast that with the return type. The return type is just a single
value of *any* valid type. And a tuple is a valid type. Therefore, the
return type can be a tuple. That's a straightforward consequence of the
basic rules of the type system. Restricting it so functions couldn't
return a tuple would be a complication to the type system, and a rather
weird one at that. And that's without even considering the complexity
and syntactical issues with your proposed `out` parameter.

-Kevin Ballard

···

On Wed, Dec 28, 2016, at 03:09 AM, Anton Zhilin via swift-evolution wrote:

Some people on the list wondered, why we have moved from tuples in
function parameters, but multiple returns are still implemented using
tuples? The following code still compiles:

*func* *position*() -> (x: Int, y: Int) { *return* (x: , y: ) }

*let* (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct.
Let’s pretend those two parameters don’t make sense as a struct.)
What I want to discuss is if we should introduce out parameters *and*
make them the default for multiple returns for Swift 4. The syntax
would look like:

*func* *position*(x: out Int, y: out Int) { x = y = }

*var* y position(x: *let* x, y: y)

out arguments can be any patterns allowed on the left side of
assignment, including wildcard pattern and tuple destructuring
pattern.

_________________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution


(Derrick Ho) #10

-1

···

On Wed, Dec 28, 2016 at 9:37 AM Tony Allevato via swift-evolution < swift-evolution@swift.org> wrote:

–1. I'm not sure there's a reason to draw a line from
removal-of-tuple-splat to removal-of-tuple-returns, other than the idea
that they both involve tuples. In a lot of languages, purely-"out"
parameters are a workaround for the fact that the language wasn't designed
to allow functions to return multiple values easily. Since Swift does allow
this, eliminating and adding "out" params is a step *backward*, not a step
forward.

"Inout" parameters at least serve an important role with respect to
in-place mutability. "Out"-only parameters don't seem like something that
would have much value in Swift.

The syntactic distinction between inputs and outputs in Swift's function
syntax is important to readability—I find the example given with "out"
params to be considerably harder to parse mentally than the version that
returns a tuple. From the point of view of making the language easy for
newcomers to learn... replacing tuple returns with "out" parameters would
be extremely harmful.

On Wed, Dec 28, 2016 at 3:10 AM Anton Zhilin via swift-evolution < > swift-evolution@swift.org> wrote:

Some people on the list wondered, why we have moved from tuples in
function parameters, but multiple returns are still implemented using
tuples? The following code still compiles:

func position() -> (x: Int, y: Int) {
    return (x: 0, y: 0)
}
let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s
pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters *and*
make them the default for multiple returns for Swift 4. The syntax would
look like:

func position(x: out Int, y: out Int) {
    x = 0
    y = 0
}
var y
position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment,
including wildcard pattern and tuple destructuring pattern.

_______________________________________________
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