# SE-0377: borrow and take parameter ownership modifiers

**URL:** <https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020>\
**Category:** Proposal Reviews\
**Created:** [October 25, 2022, 5:38pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020 "2022-10-25T17:38:43Z")\
**Posts on this page:** 15\
**Page:** 2

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [November 7, 2022, 1:53pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/21 "2022-11-07T13:53:56Z")

</div>

Though that is better aligned with other function modifiers (such as `async` and `throws`), it's worth noting that `mutating` with the former syntax already exists in the language, so to do that would be a breaking change. If the first syntax even becomes so much as a warning, we may see libraries having to do this:

```swift
#if swift(>=5.8) // or whatever version
    func foo() mutates {
        // ...body...
    }
#else
    mutating func foo() {
        // ...same body...
    }
#endif

```

So I'm not sure that would be worth it.

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [November 7, 2022, 2:23pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/22 "2022-11-07T14:23:50Z")

</div>

> [@ibex](#):
>
> This looks much better:
> 
> ```swift
> struct Foo {
> func foo() takes // `take` ownership of self
> func foo() borrows // `borrow` self
> func foo() mutates // `modify` self with `inout` semantics
> }
> 
> ```

This would introduce inconsistency with the fact that `async` and `throws` are keywords for denoting effects and already have their own set of "rules". Both are parts of their type signatures, `(Int) -> String` and `(Int) async -> String` are different (even though they have a certain subtyping relationships), while `(Int) mutates -> String` does not make sense as a standalone type signature. Effectful read-only properties were introduced in [SE-0310](https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md), allowing `get async` and `get throws` in property declarations. In the light of that, what would `get mutates` even mean?

Additionally, `throws` has counterparts in `throw` and `rethrows`. `async` has `await` and potentially `reasync`, as discussed in future directions of the corresponding proposal. I don't think `mutate` and `remutates` make sense even at a conceptual level. In this sense, `taking`, `borrowing`, and `mutating` are not function/property effect modifiers.

---

<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:** [November 7, 2022, 3:21pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/23 "2022-11-07T15:21:58Z")

</div>

> [@SwiftButLazy](#):
>
> However, don't we need some attribute declaring if it is a mutable or immutable borrow or is this covered by inout?

Rust’s notion of “mutable borrow” does indeed correspond to Swift’s `inout`. They’re slightly different (and so are the two “borrow”s) because Rust’s references are first-class values that promise a pointer representation and Swift’s are calling conventions that do not expose the representation. (For example, a `borrow`ed Int in Swift will still be passed by value because it is a small frozen trivially-copyable struct.)

---

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [November 7, 2022, 3:44pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/24 "2022-11-07T15:44:21Z")

</div>

> [@Max\_Desiatov](#):
>
> In the light of that, what would `get mutates` even mean?

Isn't `mutating get` already a thing? I'm 90% sure that `lazy` variables have an implicit `{ mutating get set }` attached to them.

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [November 7, 2022, 3:52pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/25 "2022-11-07T15:52:31Z")

</div>

Yes, that one's a weird special case, but note that it's then consistent with `mutating func`. It still stands far from effect keywords in all other aspects.

---

<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:** [November 7, 2022, 4:19pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/26 "2022-11-07T16:19:55Z")

</div>

If we want a consistency argument, `mutating` and the new proposed keywords affect how `self` behaves within the function, while also changing the `self` the function is called on. What other modifiers on functions affect `self` like this? `static`/`class`, and maybe `convenience` as a stretch. These also appear at the start of the declaration.

(I don’t put a lot of stock in consistency here, though, cause it’s clear that “before the declaration” is the default place to put modifiers in Swift, and `throws` and `async` are the unusual ones.)

---

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [November 7, 2022, 4:29pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/27 "2022-11-07T16:29:13Z")

</div>

Since `mutating get` was brought up: what about `nonmutating set`? Would that be respelled `borrowing set` now?  
Similarly, would it make sense to allow `taking get` or `taking set`?

Edit: it seems the compiler doesn't currently reject ` __consuming get` and `__ consuming set`. It even allows ` __consuming willSet` and `__ consuming didSet`, though I'm not sure why you'd use those.

---

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [November 7, 2022, 5:10pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/28 "2022-11-07T17:10:24Z")

</div>

Do we want to allow setters to borrow the new value? Currently, a setter can't mark its argument as ` __shared` _or_ `__ owned`. However, allowing that opens up a whole can of worms:

- What if a `set`, `willSet`, or `didSet` tries to have an `inout` argument?
- What does it mean for `didSet` to take its argument (`oldValue`) by anything other than `take`?
- Should `willSet` be allowed to `take` its argument (`newValue`)?

Maybe this was already discussed and I just missed it, but `willSet` and `didSet` don't seem to be mentioned in the proposal at all.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 15, 2022, 7:33pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/29 "2022-11-15T19:33:16Z")

</div>

> [@bbrk24](#):
>
> Since `mutating get` was brought up: what about `nonmutating set`? Would that be respelled `borrowing set` now?  
> Similarly, would it make sense to allow `taking get` or `taking set`?

That's an interesting question. `borrowing set` would indeed be equivalent to `nonmutating set`, but we should probably keep the existing spelling working for compatibility. As you noted, `__consuming` is currently allowed on `get` and `set` accessors, and I would say `taking` and `borrowing` ought to be allowed as well. It doesn't really make sense to allow them on `didSet` or `willSet` since those get absorbed into the setter and `modify` coroutine ABI-wise, and they always follow the ownership semantics for setting a stored property of the containing type (which would be `mutating` for a struct or `borrowing` for a class).

> [@bbrk24](#):
>
> Do we want to allow setters to borrow the new value? Currently, a setter can't mark its argument as ` __shared` _or_ `__ owned`. However, allowing that opens up a whole can of worms:
> 
> - What if a `set`, `willSet`, or `didSet` tries to have an `inout` argument?
> - What does it mean for `didSet` to take its argument (`oldValue`) by anything other than `take`?
> - Should `willSet` be allowed to `take` its argument (`newValue`)?
> 
> Maybe this was already discussed and I just missed it, but `willSet` and `didSet` don't seem to be mentioned in the proposal at all.

It might be interesting to allow `set` to borrow or `inout` its `newValue`, but I think that doing so requires further language design to work out what that means in relation to the borrow/inout access on the base of the property being set. (Similar issues cloud our ability to put `throws` on set, for instance.) So I think it makes sense to explicitly subset setters out of this initial proposal. Since `willSet` and `didSet` are tied to the default assignment behavior of stored properties, I don't think that modifying the semantics of `oldValue`/`newValue` is particularly useful.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 15, 2022, 8:35pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/30 "2022-11-15T20:35:16Z")

</div>

> [@jrose](#):
>
> (I don’t put a lot of stock in consistency here, though, cause it’s clear that “before the declaration” is the default place to put modifiers in Swift, and `throws` and `async` are the unusual ones.)

I was always in favour of prefix spelling for async/throw as well:

```
async func foo() -> Int {}
throwing func foo() -> Int {}

```

but OTOH [as mentioned above](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/22) async/throw is part of function signature so I am not so sure about it.

---

<div class="post-metadata">

**Author:** ![plaukiu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/plaukiu/32/27667_2.png) [@plaukiu](https://forums.swift.org/u/plaukiu)\
**Post date:** [November 17, 2022, 5:55pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/31 "2022-11-17T17:55:37Z")

</div>

1

Taking is an action. Owning is a state. Taking means a transference of possession.

If an owned object can be borrowed, then an owning function is a contradiction in terms, because it explicitly cuts off this possibility: 1. by scope 2. by voiding the argument.

2

Actually, the term of borrowing is also not quite there. In actuality, how many borrowers have access to the same thing? How can multiple borrowers get the same thing?  
Only 1. by reproduction, i.e. copy onto parameter or 2. by glimpsing into its argument in place, not moving or copying.

Only single-access borrowing should actually be considered borrowing.  
(Considering that its intention is to change the value, it’s not perfect as well. You wouldn’t expect a thing you lend to return changed. The contract is usually precisely that trust is given to not change it. But at least changing it is not precluded.)

3 a musing, not even a suggestion

I myself enjoy a different analogy – that of flows. Terms like conduit, flow, tapping, filling.  
One could imagine the value as a quantum of energy. Then borrowing is tapping, and mutable borrowing is switching or swapping. Or mutating.  
I like the similarity of Take and Tap and how it separates itself from mutation in situ, which is the most special case and the main antagonist.  
(I also like the `mut` of rust, as it does not only mutate, but ‘mute’ the value for the time being – not other place can have it). But it’s too poetic for the other tastes.

---

<div class="post-metadata">

**Author:** ![filip-sakel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/filip-sakel/32/8697_2.png) [@filip-sakel](https://forums.swift.org/u/filip-sakel)\
**Post date:** [November 17, 2022, 7:58pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/32 "2022-11-17T19:58:33Z")

</div>

> [@plaukiu](#):
>
> Taking is an action. Owning is a state.

Whatever modifier we choose to put in (front of?) the function, I think `mutating` needs to match `inout`. If we go with a naming scheme like `takes`, `borrows`, `mutates` then an `inout` parameter should also be spelled `mutate`. Because as it currently stands, `take` is a verb, `borrow` will be a verb and `inout` will have an adjective role.

---

<div class="post-metadata">

**Author:** ![plaukiu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/plaukiu/32/27667_2.png) [@plaukiu](https://forums.swift.org/u/plaukiu)\
**Post date:** [November 22, 2022, 8:40pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/33 "2022-11-22T20:40:05Z")

</div>

I wonder if an _-ing_ prefix is at all good.  
`mutating`

1. appears in relation to value type methods only,
2. has dual target – mutates property = mutates `self`
3. modifies _value_
4. most importantly, declares its behaviour towards the target, **not** the argument. i.e. it declares a side-effect from its body, with exactly zero relation to its arguments.

None of these points apply to ownership transfer; it

1. appears in relation to any function,
2. has a single target, no `self` pointer,
3. either modifies _place_, or does no modification at all (value is modified by `inout` only)
4. declares its behaviour towards its arguments, not its scope.

For the sake of consistency, it would necessitate a bunch of changes to the grammar of `mutating`, as well.

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [December 7, 2022, 9:26pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/34 "2022-12-07T21:26:00Z")

</div>

Thanks everyone for your feedback so far! I've kicked off a combined re-review of SE-0366 and SE-0377 focused on naming here:

> [@Combined SE-0366 (third review) and SE-0377 (second review): rename \`take\`/\`taking\` to \`consume\`/\`consuming\`](https://forums.swift.org/t/combined-se-0366-third-review-and-se-0377-second-review-rename-take-taking-to-consume-consuming/61904):
>
> Hello, Swift community! The combined third review of [SE-0366: consume operator to end the lifetime of a variable binding](https://github.com/apple/swift-evolution/blob/main/proposals/0366-move-function.md) and second review of [SE-0377: borrow and consume parameter ownership modifiers](https://github.com/apple/swift-evolution/blob/main/proposals/0377-parameter-ownership-modifiers.md) begins now and run through December 14th, 2022. Throughout the reviews for SE-0366 and SE-0377, reviewers surfaced the concern that ‘take’ is too general a name to describe ownership transfer; ‘take’ is used colloquially to describe general passing of arguments to parameters, e.g. a function takes…

Please provide further feedback on the new review thread. Thank you!

Holly Borla  
Review Manager

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [December 7, 2022, 9:29pm UTC](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020/35 "2022-12-07T21:29:56Z")

</div>

Closed on December 7, 2022, 9:29pm UTC



[Previous page](https://forums.swift.org/t/se-0377-borrow-and-take-parameter-ownership-modifiers/61020.md?page=1)
