[Proposal] Use inout at function call sites


(Trent Nadeau) #1

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are
passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the
parameter is written at the function declaration. It should be
replaced so that `inout` is used in both locations so that the call
site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read
as "address of" and creates a pointer. While very useful in C due to
its pervasive use of pointers, its meaning is not the same and
introduces an unnecessary syntactic stumbling block from users coming
from C. Removing this operator and using `inout` removes this
stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration
is written and does not imply that the argument may (and likely will)
change. Using `inout` stands out, making it clear on first read that
the variable may change.

It is also possible that Swift may add Rust-like borrowing in the
future. In that case, the `&` symbol would be better used for a
borrowed reference. Note that Rust uses the same symbol for declaring
a borrowed reference and creating one, creating a nice symmetry in
that respect of the language. I think Swift would want to have such
symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

···

--
Trent Nadeau


(Dmitri Gribenko) #2

Since there is an implicit conversion from &x expression to
UnsafePointer (for C interop), I have seen so many times people write
buggy code with the & operator, assuming that it is returning a stable
inner pointer to the data structure, like in C. I don't have a
preference for the replacement, but I strongly believe that & is the
wrong way to spell this operation, because of the strong (and wrong!)
connection with C syntax that people tend to make. 'inout' keyword at
the call site sounds like a fine replacement to me.

Dmitri

···

On Fri, Jan 29, 2016 at 2:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org> wrote:

The `&` prefix operator is a holdover from C where it is usually read as
"address of" and creates a pointer. While very useful in C due to its
pervasive use of pointers, its meaning is not the same

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Jarod Long) #3

+1 for the same reason.

Jarod

···

On Jan 29, 2016, at 14:50, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

+1. Really like the declaration and use symmetry.

On Jan 29, 2016, at 4:48 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

+1.

-- E

On Jan 29, 2016, at 3:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Nate Birkholz) #4

+1

···

Sent from my iPhone, please excuse brevity and errors

On Jan 29, 2016, at 3:05 PM, Jarod Long via swift-evolution <swift-evolution@swift.org> wrote:

+1 for the same reason.

Jarod

On Jan 29, 2016, at 14:50, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

+1. Really like the declaration and use symmetry.

On Jan 29, 2016, at 4:48 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

+1.

-- E

On Jan 29, 2016, at 3:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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

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


(Jordan Rose) #5

+1 from me, but I suggest finding some real-world examples of inout (and UnsafePointer) and showing those, rather than a made-up add1. The fact that we currently require '&' for Unsafe-(immutable)-Pointer might make this a bit less nice than it otherwise would be.

(We've talked about allowing pass-by-value for UnsafePointer, but that has its own pros and cons, and should be discussed separately.)

Jordan

···

On Jan 29, 2016, at 14:44, Trent Nadeau via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Joe Groff) #6

Yeah, I like getting away from the baggage of the '&x' notation too. Implicit C pointer interop assumes that the C function has Swift-like by-value (for const) or inout-like (for non-const) semantics, and I like the idea of making that more explicit in the call site.

-Joe

···

On Jan 29, 2016, at 2:49 PM, Dmitri Gribenko via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Jan 29, 2016 at 2:44 PM, Trent Nadeau via swift-evolution > <swift-evolution@swift.org> wrote:

The `&` prefix operator is a holdover from C where it is usually read as
"address of" and creates a pointer. While very useful in C due to its
pervasive use of pointers, its meaning is not the same

Since there is an implicit conversion from &x expression to
UnsafePointer (for C interop), I have seen so many times people write
buggy code with the & operator, assuming that it is returning a stable
inner pointer to the data structure, like in C. I don't have a
preference for the replacement, but I strongly believe that & is the
wrong way to spell this operation, because of the strong (and wrong!)
connection with C syntax that people tend to make. 'inout' keyword at
the call site sounds like a fine replacement to me.


(Erica Sadun) #7

+1.

-- E

···

On Jan 29, 2016, at 3:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Erica Sadun) #8

I started poking around. It looks like the rules for calls with functions are different from those with operators. At least in the following example, the operator version doesn't need the &. Any idea why?

-- Erica

//--------------------------------------------------------------
// Stream Printing
//--------------------------------------------------------------
import Darwin
import Foundation

public struct StdErrStream: OutputStreamType {
    public mutating func write(string: String) {
        puts(string.cStringUsingEncoding(NSUTF8StringEncoding)!)
    }
}

var stdStream = StdErrStream()
print("hello world", toStream: &stdStream)

vs

//--------------------------------------------------------------
// MARK: Conditional Assignment
//--------------------------------------------------------------

infix operator =? {}

/// Conditionally assign optional value to target via unwrapping
/// Thanks, Mike Ash
func =?<T>(inout target: T, newValue: T?) {
    if let unwrapped = newValue { target = unwrapped }
}

import UIKit
var image = UIImage()
var replacement = [#Image(imageLiteral: "Screen Shot 2016-01-29 at 4.35.48 PM.png")#]
image =? UIImage(named: "DoesNotExist")

-- E

···

On Jan 29, 2016, at 4:23 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

+1 from me, but I suggest finding some real-world examples of inout (and UnsafePointer) and showing those, rather than a made-up add1. The fact that we currently require '&' for Unsafe-(immutable)-Pointer might make this a bit less nice than it otherwise would be.

(We've talked about allowing pass-by-value for UnsafePointer, but that has its own pros and cons, and should be discussed separately.)

Jordan

On Jan 29, 2016, at 14:44, Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Matthew Johnson) #9

+1. Really like the declaration and use symmetry.

···

On Jan 29, 2016, at 4:48 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

+1.

-- E

On Jan 29, 2016, at 3:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Lily Ballard) #10

-1

I feel like the people who are voting +1 probably don't actually *use*
inout parameters very often, because it seems very obvious that
requiring the label "inout" at the function call site is extremely
unwieldy. inout parameters aren't some weird edge case that we want to
penalize, they're a perfectly legitimate feature of the language, and
they should be relatively easy to call.

-Kevin Ballard

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are
passed with the `&` prefix operator. For example:


var n = 5 add1(&n) // n is now 6 ```

This operator does not fit with the rest of the language nor how the
parameter is written at the function declaration. It should be replaced
so that `inout` is used in both locations so that the call site above
would instead be written as:

```swift add1(inout n) // symmetric and now obvious that n can
change \`\`\`

\*Discussion thread TBD\*

\#\# Motivation

The \`&amp;\` prefix operator is a holdover from C where it is usually read as
&quot;address of&quot; and creates a pointer\. While very useful in C due to its
pervasive use of pointers, its meaning is not the same and introduces an
unnecessary syntactic stumbling block from users coming from C\. Removing
this operator and using \`inout\` removes this stumbling block due to the
semantic change\.

This operator is also disconnected from how the function declaration is
written and does not imply that the argument may \(and likely will\)
change\. Using \`inout\` stands out, making it clear on first read that the
variable may change\.

It is also possible that Swift may add Rust\-like borrowing in the
future\. In that case, the \`&amp;\` symbol would be better used for a borrowed
reference\. Note that Rust uses the same symbol for declaring a borrowed
reference and creating one, creating a nice symmetry in that respect of
the language\. I think Swift would want to have such symmetry as well\.

\#\# Detailed design

\`\`\` in\-out\-expression → inout identifier \`\`\`

\#\# Alternatives Considered

Keeping the syntax as it currently is\.

<details class='elided'>
<summary title='Show trimmed content'>&#183;&#183;&#183;</summary>

On Fri, Jan 29, 2016, at 02:44 PM, Trent Nadeau via swift\-evolution wrote:
>
> \-\-
> Trent Nadeau
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
> swift\-evolution mailing list swift\-evolution@swift\.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

</details>

(Zachary Waldowski) #11

-1. I understand the semantic reasons, but I find it really hard to read
at the call-site. I don't see "&" as exclusively a holdover from C; if
we didn't have it, it'd be an unused sigil that'd probably be used by
something like addressing due to its prevalence in other languages.

Cheers. Zachary Waldowski zach@waldowski.me

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are
passed with the `&` prefix operator. For example:


var n = 5 add1(&n) // n is now 6 ```

This operator does not fit with the rest of the language nor how the
parameter is written at the function declaration. It should be replaced
so that `inout` is used in both locations so that the call site above
would instead be written as:

```swift add1(inout n) // symmetric and now obvious that n can
change \`\`\`

\*Discussion thread TBD\*

\#\# Motivation

The \`&amp;\` prefix operator is a holdover from C where it is usually read as
&quot;address of&quot; and creates a pointer\. While very useful in C due to its
pervasive use of pointers, its meaning is not the same and introduces an
unnecessary syntactic stumbling block from users coming from C\. Removing
this operator and using \`inout\` removes this stumbling block due to the
semantic change\.

This operator is also disconnected from how the function declaration is
written and does not imply that the argument may \(and likely will\)
change\. Using \`inout\` stands out, making it clear on first read that the
variable may change\.

It is also possible that Swift may add Rust\-like borrowing in the
future\. In that case, the \`&amp;\` symbol would be better used for a borrowed
reference\. Note that Rust uses the same symbol for declaring a borrowed
reference and creating one, creating a nice symmetry in that respect of
the language\. I think Swift would want to have such symmetry as well\.

\#\# Detailed design

\`\`\` in\-out\-expression → inout identifier \`\`\`

\#\# Alternatives Considered

Keeping the syntax as it currently is\.

<details class='elided'>
<summary title='Show trimmed content'>&#183;&#183;&#183;</summary>

On Fri, Jan 29, 2016, at 05:44 PM, Trent Nadeau via swift\-evolution wrote:
>
> \-\-
> Trent Nadeau
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
> swift\-evolution mailing list swift\-evolution@swift\.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

</details>

(Jordan Rose) #12

Can you show us some examples? I remember your replace(_:with:); what else do you use?

Jordan

···

On Jan 29, 2016, at 17:32 , Kevin Ballard via swift-evolution <swift-evolution@swift.org> wrote:

-1

I feel like the people who are voting +1 probably don't actually use inout parameters very often, because it seems very obvious that requiring the label "inout" at the function call site is extremely unwieldy. inout parameters aren't some weird edge case that we want to penalize, they're a perfectly legitimate feature of the language, and they should be relatively easy to call.

-Kevin Ballard

On Fri, Jan 29, 2016, at 02:44 PM, Trent Nadeau via swift-evolution wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Jeremy Kates) #13

Not having the deep C background, the current syntax has never bothered me, but if it causes confusion for those that do, I think clarity makes logical sense.
+1

···

Sent from my iPhone

On Jan 29, 2016, at 4:44 PM, Trent Nadeau via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Jordan Rose) #14

The reasoning here was that the operator itself would be enough signal to tell you that it's mutating one of its arguments. "&count += 1" would be a little too much.

Similarly, mutating methods take 'self' inout, but as noted before you aren't required to write 'mutating' at the call site, because it's assumed the name will be signal enough. This doesn't scale to arbitrary numbers of arguments, though, especially when you normally don't even think about some of your arguments being changed by a function call.

Mutating functions and assignment operators are fairly common (at least when not eschewing imperative programming). General inout parameters are not.

Jordan

P.S. At one point we thought about requiring you to declare "assignment" in your operator declaration, and disallowing inout parameters from arbitrary other operators, but that didn't actually turn into a proposal. It's not a bad idea, though—just a bit of compiler-enforced consistency.

···

On Jan 29, 2016, at 15:48 , Erica Sadun <erica@ericasadun.com> wrote:

I started poking around. It looks like the rules for calls with functions are different from those with operators. At least in the following example, the operator version doesn't need the &. Any idea why?

-- Erica

//--------------------------------------------------------------
// Stream Printing
//--------------------------------------------------------------
import Darwin
import Foundation

public struct StdErrStream: OutputStreamType {
    public mutating func write(string: String) {
        puts(string.cStringUsingEncoding(NSUTF8StringEncoding)!)
    }
}

var stdStream = StdErrStream()
print("hello world", toStream: &stdStream)

vs

//--------------------------------------------------------------
// MARK: Conditional Assignment
//--------------------------------------------------------------

infix operator =? {}

/// Conditionally assign optional value to target via unwrapping
/// Thanks, Mike Ash
func =?<T>(inout target: T, newValue: T?) {
    if let unwrapped = newValue { target = unwrapped }
}

import UIKit
var image = UIImage()
var replacement = [#Image(imageLiteral: "Screen Shot 2016-01-29 at 4.35.48 PM.png")#]
image =? UIImage(named: "DoesNotExist")

-- E

On Jan 29, 2016, at 4:23 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

+1 from me, but I suggest finding some real-world examples of inout (and UnsafePointer) and showing those, rather than a made-up add1. The fact that we currently require '&' for Unsafe-(immutable)-Pointer might make this a bit less nice than it otherwise would be.

(We've talked about allowing pass-by-value for UnsafePointer, but that has its own pros and cons, and should be discussed separately.)

Jordan

On Jan 29, 2016, at 14:44, Trent Nadeau via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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


(Brent Royal-Gordon) #15

add1(&n) // n is now 6
add1(inout n) // symmetric and now obvious that n can change

I'm not a really big fan of this change; despite being longer, `inout n` is less visible to me than `&n`. But this is a relatively weak preference—I could certainly live with it.

More important than changing the symbol might be restricting its use. I don't see any particularly good reason to permit you to say `let x = &y`. Far better to use `withUnsafePointer()` to control the scope of the pointer, or at least say something like `let x = unsafeInoutPointer(&y)` to acknowledge that you're circumventing memory safety and possibly taking a pointer to a temporary. Basically, I think `&` or `inout` or however we spell it should only be allowed as a parameter, not just anywhere in any expression.

···

--
Brent Royal-Gordon
Architechies


(Trent Nadeau) #16

C# uses its `ref` keyword in both function declarations and call sites (see
https://msdn.microsoft.com/en-us/library/14akc2c7.aspx), and I don't think
people consider that syntax to be penalized or an edge case.

···

On Fri, Jan 29, 2016 at 8:32 PM, Kevin Ballard via swift-evolution < swift-evolution@swift.org> wrote:

-1

I feel like the people who are voting +1 probably don't actually *use*
inout parameters very often, because it seems very obvious that requiring
the label "inout" at the function call site is extremely unwieldy. inout
parameters aren't some weird edge case that we want to penalize, they're a
perfectly legitimate feature of the language, and they should be relatively
easy to call.

-Kevin Ballard

On Fri, Jan 29, 2016, at 02:44 PM, Trent Nadeau via swift-evolution wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

--
Trent Nadeau
*_______________________________________________*
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

--
Trent Nadeau


#17

inout vs & doesn’t look that ugly in a simple single argument function, but what if you have many:

getUserData(userid, &username, &groupid, &shell) // Current syntax
getUserData(userid, inout username, inout groupid, inout shell) // Proposal

Yes, for the above one should use something better ( userData=getUserData(userid) ). But, I’m sure there are valid scenario where one wants multiple inout parameters. And such an example must be provided to visualize the impact of moving from & to inout.

Just realizing that the above syntax is without label, even the proposal doesn’t show the use of the inout with labels…
So the current proposal changes:
add(number: &n)
to
add(inout number: n) // Perfect symmetry
add(number: inout n) // Matching token location

So with my bad example from above changing:
getUserData(id: userid, name: &username, gid: &groupid, shell: &shell)
to:
getUserData(id: userid, inout name: username, inout gid: groupid, inout shell: shell)
getUserData(id: userid, name: inout username, gid: inout groupid, shell: inout shell)

That’s a lot of word, syntax highlighting does help a bit but I do not want to rely on it.

Dany

···

Le 29 janv. 2016 à 17:44, Trent Nadeau via swift-evolution <swift-evolution@swift.org> a écrit :

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

```swift
add1(inout n) // symmetric and now obvious that n can change


(Trent Nadeau) #18

That fact that the & operator is required for immutable pointers definitely
makes this change not-so-great unless we add the pass by value for
immutable.

For instance for C's memcpy which is defined in C as:

void *memcpy(void *dest, const void *src, size_t n)

is imported into Swift as:

public func memcpy(_: UnsafeMutablePointer<Void>, _: UnsafePointer<Void>,
_: Int) -> UnsafeMutablePointer<Void>

It would currently be called like:

var src: Float = 5.3
var dest: Float = 0.0
memcpy(&dest, &src, sizeof(Float))

If we don't change how UnsafePointer is called and just replace "&" with
"inout ", then it becomes:

memcpy(inout dest, inout src, sizeof(Float))

And now the "src" part of the call in now basically lying.

If we can just pass src directly (assuming that's what you meant by
pass-by-value), then it would be:

memcpy(inout dest, src, sizeof(Float))

which seems nicer than both the previous versions.

Would the UnsafePointer change need to be a proposal that is a predecessor
to this one?

P.S. It would be nice to be able to pass constants to UnsafePointer and not
using "&" for inout and UnsafePointer would allow that I think.

···

On Fri, Jan 29, 2016 at 6:23 PM, Jordan Rose <jordan_rose@apple.com> wrote:

+1 from me, but I suggest finding some real-world examples of inout (and
UnsafePointer) and showing those, rather than a made-up add1. The fact that
we currently require '&' for Unsafe-(immutable)-Pointer might make this a
bit less nice than it otherwise would be.

(We've talked about allowing pass-by-value for UnsafePointer, but that has
its own pros and cons, and should be discussed separately.)

Jordan

On Jan 29, 2016, at 14:44, Trent Nadeau via swift-evolution < > swift-evolution@swift.org> wrote:

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites

* Proposal: TBD
* Author(s): [Trent Nadeau](http://github.com/tanadeau)
* Status: TBD
* Review manager: TBD

## Introduction

Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example:

func add1(inout num: Int) {
    num += 1
}

var n = 5
add1(&n) // n is now 6

This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as:

add1(inout n) // symmetric and now obvious that n can change

*Discussion thread TBD*

## Motivation

The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change.

This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change.

It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well.

## Detailed design

in-out-expression → inout identifier

## Alternatives Considered

Keeping the syntax as it currently is.

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

--
Trent Nadeau


(Benedikt Terhechte) #19

+1

···

https://github.com/tanadeau/swift-evolution/blob/master/proposals/00xx-use-inout-at-func-call-site.md

# Use `inout` at Function Call Sites * Proposal: TBD * Author(s): [Trent Nadeau](http://github.com/tanadeau) * Status: TBD * Review manager: TBD ## Introduction Currently when a function has `inout` parameters, the arguments are passed with the `&` prefix operator. For example: ```swift func add1(inout num: Int) { num += 1 } var n = 5 add1(&n) // n is now 6 ``` This operator does not fit with the rest of the language nor how the parameter is written at the function declaration. It should be replaced so that `inout` is used in both locations so that the call site above would instead be written as: ```swift add1(inout n) // symmetric and now obvious that n can change ``` *Discussion thread TBD* ## Motivation The `&` prefix operator is a holdover from C where it is usually read as "address of" and creates a pointer. While very useful in C due to its pervasive use of pointers, its meaning is not the same and introduces an unnecessary syntactic stumbling block from users coming from C. Removing this operator and using `inout` removes this stumbling block due to the semantic change. This operator is also disconnected from how the function declaration is written and does not imply that the argument may (and likely will) change. Using `inout` stands out, making it clear on first read that the variable may change. It is also possible that Swift may add Rust-like borrowing in the future. In that case, the `&` symbol would be better used for a borrowed reference. Note that Rust uses the same symbol for declaring a borrowed reference and creating one, creating a nice symmetry in that respect of the language. I think Swift would want to have such symmetry as well. ## Detailed design ``` in-out-expression → inout identifier ``` ## Alternatives Considered Keeping the syntax as it currently is.

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


(Andrew Trick) #20

There's no arguing with the logic that & is inappropriate, and no arguing with Chris’ point that this is a bad place for a keyword or attribute.

Since no one has mentioned the obvious on this thread (although it must have been considered) I’ll just say it...

copy out or inout:
swap(x=, y=)

copy in:
sync(=x, =y)

Alternatively: &= as a kind of move operator.

I would even be ok eliminating inout in favor of move semantics, but I don’t think that will fly and doesn’t handle interop.

Andy

···

On Jan 29, 2016, at 3:39 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 29, 2016, at 2:49 PM, Dmitri Gribenko via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Jan 29, 2016 at 2:44 PM, Trent Nadeau via swift-evolution >> <swift-evolution@swift.org> wrote:

The `&` prefix operator is a holdover from C where it is usually read as
"address of" and creates a pointer. While very useful in C due to its
pervasive use of pointers, its meaning is not the same

Since there is an implicit conversion from &x expression to
UnsafePointer (for C interop), I have seen so many times people write
buggy code with the & operator, assuming that it is returning a stable
inner pointer to the data structure, like in C. I don't have a
preference for the replacement, but I strongly believe that & is the
wrong way to spell this operation, because of the strong (and wrong!)
connection with C syntax that people tend to make. 'inout' keyword at
the call site sounds like a fine replacement to me.

Yeah, I like getting away from the baggage of the '&x' notation too. Implicit C pointer interop assumes that the C function has Swift-like by-value (for const) or inout-like (for non-const) semantics, and I like the idea of making that more explicit in the call site.