# About reassigning self in classes

**URL:** <https://forums.swift.org/t/about-reassigning-self-in-classes/33813>\
**Category:** Using Swift\
**Created:** [February 14, 2020, 8:10am UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813 "2020-02-14T08:10:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [February 14, 2020, 8:10am UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/1 "2020-02-14T08:10:41Z")

</div>

This is a spin-off from [this thread](https://forums.swift.org/t/extending-a-class-bound-type-to-conform-to-a-protocol-extended-with-mutating-functions/33762/12).

As far as I can see, Swift seems to actively prevent us from reassigning `self` in classes:

```swift
class C {
    func reassignSelf(to other: C) {
        self = other // ERROR: Cannot assign to value: 'self' is immutable
    }
}

```

and

```swift
class C {
    mutating func reassignSelf(to other: C) { // ERROR: 'mutating' isn't valid on methods in classes or class-bound protocols
        self = other // ERROR: Cannot assign to value: 'self' is immutable
    }
}

```

So I'm assuming that we are not allowed to reassign self in classes (please correct me if I'm wrong).

* * *

## But:

**It _is_ possible to reassign self in a class** via a protocol's default implementation:

```swift
protocol P {
    mutating func reassignSelf(to other: Self)
}

extension P {
    mutating func reassignSelf(to other: Self) { self = other }
}

class C : P {
    var v: Int
    var addressStr: String { "\(Unmanaged.passUnretained(self).toOpaque())" }
    init(v: Int) { self.v = v }
}

func test() {
    let a = C(v: 1)
    var b = C(v: 2)
    let c = b

    print(a.v, a.addressStr) // 1 0x0000000100703c70
    print(b.v, b.addressStr) // 2 0x0000000100703c90
    print(c.v, c.addressStr) // 2 0x0000000100703c90
    print(a === b) // false
    print(a === c) // false
    print(b === c) // true

    b.reassignSelf(to: a)

    print(a.v, a.addressStr) // 1 0x0000000100703c70
    print(b.v, b.addressStr) // 1 0x0000000100703c70
    print(c.v, c.addressStr) // 2 0x0000000100703c90
    print(a === b) // true <-- These are now referencing the same instance.
    print(a === c) // false
    print(b === c) // false
}
test()

```

* * *

So, while Swift disallows reassigning self in classes, it allows us to do just that (I guess even accidentally) via a default implementation of some protocol ...

It would be interesting to learn more about the rationale behind this seemingly inconsistent behavior, that is:

- Why is it important to prevent reassigning self in classes?

- Why is it not prevented to (even accidentally) do so via a protocol's default implementation?

---

<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:** [February 14, 2020, 8:30am UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/2 "2020-02-14T08:30:25Z")

</div>

This is discussed at length [here](https://bugs.swift.org/browse/SR-142) and [here](https://forums.swift.org/t/proposal-intermediate-mutation-qualifier-for-protocol-functions-on-reference-types/401) and [here](https://forums.swift.org/t/protocols-mutating-and-value-vs-reference-types/2395) and [here](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066).

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [February 14, 2020, 9:28am UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/3 "2020-02-14T09:28:31Z")

</div>

Thanks for providing those links! I've read them through and they are mostly about the problem as formulated in the [forked thread](https://forums.swift.org/t/extending-a-class-bound-type-to-conform-to-a-protocol-extended-with-mutating-functions/33762), and while they provide answers to the problem from that perspective, they don't quite answer the specific questions of _this_ thread, namely:

Given the program in the OP (which demonstrates that it _is_ possible to reassign self in classes, and that the way it is done is such that it might happen accidentally):

> [@Jens](#):
>
> - Why is it important to prevent reassigning self in classes? _(rhetorical question)_
> - Why is it then **not** prevented to (even accidentally) do so via a protocol's default implementation?

* * *

I've quoted the parts of the linked discussions that comes closest to answering these questions here:

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/6):
>
> Until we have the "this protocol is only for value types" part, we can't do the "treat `mutating` as if it is not there in reference types" part. It's also not obviously a good idea since an immutable class type is pretty much indistinguishable from a value type except for `ObjectIdentifier` (and `===` ).
> 
> (A long time ago @dabrahams and I talked about disallowing classes from conforming to protocols with `mutating` requirements, which is similar. But at this point it'd be massively source-breaking to do so.)

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/7):
>
> One thing I have wondered about related to this issue is why Swift does not allow writing:
> 
> ```swift
> class Foo {
> mutating func bar() {
> self = Foo()
> }
> }
> 
> ```

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/8):
>
> We could allow it, sure. But it would only change _this_ reference, not any other references pointing to the same object, and _not_ having `mutating` doesn't prevent you from changing stored properties (see [Avoiding unbreakable reference cycle with value types and closures?](https://forums.swift.org/t/avoiding-unbreakable-reference-cycle-with-value-types-and-closures/18757/17)). So it's left out of the language to avoid introducing a point of confusion.
> 
> Have you come across a situation where you would have wanted this?

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/9):
>
> No, I just noted it would be a generally consistent and unambiguous extension of the current meaning.

* * *

So what I'm saying is that after reading and understanding the above (and the other parts of the linked discussions) I've yet to see the rationale for the seemingly inconsistent behavior demonstrated by the program in the OP. That is:  
**Why does Swift allow a default implementation of a protocol to reassign self of a class from under our feet** (while actively _preventing_ us from doing it explicitly within the class) **?**

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [February 14, 2020, 1:16pm UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/4 "2020-02-14T13:16:00Z")

</div>

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/8):
>
> So it's left out of the language to avoid introducing a point of confusion.

I feels like this might be part of the reason.

Reassigning self in class may mean 2 things:

- Change only the reference calling the function
- Change **all** references referring to the class

Which ever we choose is gonna cause confusion to the other half (not to mention complexity to do the latter).

Reassigning self in protocol doesn’t seem to have as many interpretation.

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [February 14, 2020, 1:20pm UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/5 "2020-02-14T13:20:00Z")

</div>

Yes, this:

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/8):
>
> So it's left out of the language to avoid introducing a point of confusion.

answers the first question:

> [@Jens](#):
>
> Why is it important to prevent reassigning self in classes?

But not the second:

> [@Jens](#):
>
> Why is it not prevented to (even accidentally) do so via a protocol's default implementation?

If the following is your answer to that second question:

> [@Lantua](#):
>
> Reassigning self in protocol doesn’t seem to have as many interpretation.

Then I can't see what you mean by that.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [February 14, 2020, 1:22pm UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/6 "2020-02-14T13:22:17Z")

</div>

To me

- reassigning in class may mean _this reference_ or _all reference_, but
- reassigning protocol may only mean _this reference_ (since it may apply to value type).

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [February 14, 2020, 1:28pm UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/7 "2020-02-14T13:28:11Z")

</div>

But the effect is the same (see demonstration program in OP) no matter if the reassignment is done via a default protocol implementation of a method, or if it had been allowed in a method on the class.

And unless I'm misunderstanding the following:

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/7):
>
> One thing I have wondered about related to this issue is why Swift does not allow writing:
> 
> ```swift
> class Foo {
> mutating func bar() {
> self = Foo()
> }
> }
> 
> ```

> [@Mutating Function on Class Type (Possible bug?)](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/8):
>
> We could allow it, sure. But it would only change _this_ reference, not any other references pointing to the same object, and _not_ having `mutating` doesn't prevent you from changing stored properties (see [Avoiding unbreakable reference cycle with value types and closures?](https://forums.swift.org/t/avoiding-unbreakable-reference-cycle-with-value-types-and-closures/18757/17)). So it's left out of the language to avoid introducing a point of confusion.

The answer from @jrose seems to suggest that assigning self of a class (no matter how) is something that is meant to be left out of the language.

But it's _not_ left out of the language (as shown by the demonstration program). And I'd like to know if it is

1. Expected behavior, working as designed (and if so, why allowing this indirect form that can happen accidentally via a default implementation of a protocol, while disallowing the explicit form in the class)?
2. An unfortunate by-product that can't be helped
3. A bug (ie it shouldn't be allowed, because it's meant to be "left out of the language to avoid introducing a point of confusion").

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [February 14, 2020, 1:42pm UTC](https://forums.swift.org/t/about-reassigning-self-in-classes/33813/8 "2020-02-14T13:42:22Z")

</div>

> [@Jens](#):
>
> But the effect is the same (see demonstration program in OP) no matter if the reassignment is done via a default protocol implementation of a method, or if it had been allowed in a method on the class.

Not really, what if mutating in class reassign _all references_ pointing to it (which frankly, is more or less the same as non-mutating function, but there will be people thinking like that for sure).

Alternatives would be:

- Disallow `P.reassignSelf` specifically for class types.
- Disallow any class types to conform to `P`.

None seems to be obviously better choice.

> [@Jens](#):
>
> And I'd like to know if it is

Probably need the core team to answer that. Anyhow, it’s a good thought exercise. 🤗
