# \[Style\] Explicit self when referencing instance member

**URL:** <https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173>\
**Category:** Using Swift\
**Created:** [March 4, 2019, 12:46am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173 "2019-03-04T00:46:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 12:46am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/1 "2019-03-04T00:46:45Z")

</div>

This was discussed previously either to always require `self` [SE-0009](https://github.com/apple/swift-evolution/blob/master/proposals/0009-require-self-for-accessing-instance-members.md) (rejected), or have an optional compiler warning (rejected).

Let's discuss whether and when this should be a recommended practice.

## Required vs Optional

There is only one case where you are _required_ to write explicit `self` – to refer to a member shadowed by another variable.

Other cases are optional (for `self` in closures see below), and are open to discussion whether it should be a recommended practice.

## Criteria

To decide whether or not to use explicit `self` when it is optional.

The arguments are:

- it reduces errors
- it improves code readability

The errors reported from not using explicit `self` boil down to:

1. confused shadowing
2. unexpected strong reference to `self`

## 1. (Required) Instance member is shadowed

> ****
>
> Common shadowing scenarios. Explicit `self` is required.
> 
> 1.a Argument to initializer
> 
> ```swift
> class Style1a {
> init(bar: Int) {
> self.bar = bar
> }
>     
> let bar: Int
> }
> 
> ```
> 
> 1.b Local variable
> 
> ```swift
> class Style1b {
> var bar: Int = 0
> 
> func foo() {
> let bar = 42
> self.bar = bar
> }
> }
> 
> ```

## 2. Confused shadowing

> ****
>
> ### 2.1 Readability of shadowed code
> 
> ```swift
> class Style21a {
> func foo() {
> if var bar = bar {
> bar = bar + 1
> }
> bar = 42
> }
>     
> var bar: Int?
> }
> 
> ```
> 
> ```swift
> class Style21b {
> func foo() {
> if let bar = self.bar {
> self.bar = bar + 1
> }
> self.bar = 42
> }
>     
> var bar: Int?
> }
> 
> ```
> 
> Pros of explicit `self`:
> 
> - Easier to reason, you can always tell when it refers to instance member
> 
> Cons:
> 
> - When reading, `self.` adds noise
> 
> Alternatives:
> 
> - Review the code in full, follow logic flow
> - `IDE` Review with "highlight all appearances of the selected symbol in the enclosing code scope"
> - `IDE` Rely on syntax highlighting difference for instance and non-instance variables
> 
> ### 2.2 Adding shadowing
> 
> > I just copy-pasted a working code block
> 
> Starting with this code:
> 
> ```swift
> class Style22 {
> func foo() {
> bar += 1
> }
>     
> var bar: Int = 0
> }
> 
> ```
> 
> And then at some point introducing shadowing on line 3:
> 
> ```swift
> class Style22 {
> func foo() {
> var bar = 42
> bar += 1
> }
>     
> var bar: Int = 0
> }
> 
> ```
> 
> This happens when pasting code, or just by adding local variable.
> 
> Pros of explicit `self`:
> 
> - There will be no shadowing
> - Compiler might warn you of unused local variable, or assigning to read-only variable, but this depends on code pasted
> - When reading, you can always tell it refers to instance member
> 
> Cons:
> 
> - You might never add shadowing, `self` is unneeded
> - When reading, `self.` adds noise
> 
> Alternatives:
> 
> - Cover the code with tests to ensure proper behavior
> - Review the code in full, follow logic flow
> - `IDE` Review with "highlight all appearances of the selected symbol in the enclosing code scope"
> - `IDE` Rely on syntax highlighting difference for instance and non-instance variables
> - `IDE` could warn you that pasted code introduces shadowing
> 
> ### 2.3 Removing shadowing
> 
> > I thought it was a local variable
> 
> Starting with this code:
> 
> ```swift
> class Style23 {
> func foo() {
> var bar = 42
> bar += 1
> }
>     
> var bar: Int = 0
> }
> 
> ```
> 
> And then at some point removing line 3:
> 
> ```swift
> class Style23 {
> func foo() {
> bar += 1
> }
>     
> var bar: Int = 0
> }
> 
> ```
> 
> In a more complex code you might believe you still have a local variable.
> 
> Pros of explicit `self`:
> 
> - If you miss explicit `self`, linter will warn you, forcing a review
> 
> Cons:
> 
> - You have to update more code with `self`, if this was intentional
> 
> Alternatives:
> 
> - Cover the code with tests to ensure proper behavior
> - Review the code in full, follow logic flow
> - `IDE` Review with "highlight all appearances of the selected symbol in the enclosing code scope"
> - `IDE` Rely on syntax highlighting difference for instance and non-instance variables
> - `IDE` could warn you of removed shadowing

## 3. Unexpected strong reference to self

> ****
>
> Note that confused shadowing could lead to unexpected strong reference, but we need to reason about them separately.
> 
> ### Exercise 1
> 
> Can you tell the line that introduces a reference cycle?
> 
> ```swift
> let s = Style30()
> s.some = s.bar
> s.some = s.nada
> s.some = s.niente
> 
> ```
> 
> What if I move this code inside a method? (`bar`, `nada`, and `niente` are still members of this class)
> 
> ```swift
> class Style30 {
> var some: Any?
>     
> func foo() {
> some = bar
> some = nada
> some = niente
> }
> 
> ```
> 
> And if I add `self`?
> 
> ```swift
> class Style30 {
> var some: Any?
> 
> func foo() {
> self.some = self.bar
> self.some = self.nada
> self.some = self.niente
> }
> 
> ```
> 
> Does `self` reveal a reference cycle?
> 
> Here is the rest of the class:
> 
> ```swift
> class Style30 {
> var some: Any?
> 
> func bar() {}
> let nada: Int = 42
> let niente = Inner()
>     
> class Inner {}
> }
> 
> ```
> 
> Writing `self` does not reveal captured reference. To reason about references, you need to see the types involved, and have an implicit knowledge that method reference captures `self`. Nothing conveys this in language syntax – this is an unfortunate design deficiency.
> 
> ### Exercise 2
> 
> Can you tell the line that introduces a reference cycle?
> 
> ```swift
> class Style30b {
> var some: Any?
>     
> func foo() {
> self.some = {
> self.bar()
> self.nada
> self.niente
> self.niente.x
> }
> }
>     
> func bar() {}
> let nada: Int = 42
> let niente = Inner()
>     
> class Inner { let x = 11 }
> }
> 
> ```
> 
> Any reference to instance member inside a closure needs that instance captured. So all the lines 6-9 need `self` captured in that closure, which introduces reference cycle when that closure stored back on the instance.
> 
> ### 3.1 Method reference
> 
> ```swift
> class Style31a {
> init() {
> some = bar
> }
> var some: Any?
> func bar() {}
> }
> 
> ```
> 
> ```swift
> class Style31b {
> init() {
> self.some = self.bar
> }
> var some: Any?
> func bar() {}
> }
> 
> ```
> 
> Line 3 introduces reference cycle.
> 
> Pros of explicit `self`:
> 
> - If you miss `self`, linter will warn you, forcing a review
> 
> Cons:
> 
> - Explicit `self` doesn't reveal captured `self`
> - When reading, `self.` adds noise
> - More typing
> 
> Alternatives:
> 
> - Review the code in full, with the types involved
> 
> The compiler might be patched [SR-8536](https://bugs.swift.org/browse/SR-8536 "Warn on member assignments capturing self"), requiring you to write `self` in this case. But if you write `self` everywhere, how does that help?
> 
> ### 3.2 Closure
> 
> ```swift
> class Style32 {
> init() {
> some = {
> bar()
> }
> }
> var some: Any?
> func bar() {}
> }
> 
> ```
> 
> > Call to method 'bar' in closure requires explicit 'self.' to make capture semantics explicit
> 
> ```swift
> class Style32 {
> init() {
> self.some = {
> self.bar()
> }
> }
> var some: Any?
> func bar() {}
> }
> 
> ```
> 
> Since any instance reference will need `self` captured, compiler now requires explicit `self` in this case.
> 
> Pros of explicit `self`:
> 
> - If you miss `self`, ~~linter~~ compiler emits error, forcing a review
> 
> Cons:
> 
> - When reading, `self.` adds noise
> - More typing
> 
> **Pitch:** I believe, forcing explicit `self` in this case was a confused decision. You should be able to tell instance members by other means, see shadowing above. And to convey explicit capture of `self` there is a cleaner syntax – capture list:
> 
> ```swift
> class Style32c {
> init() {
> some = { [self] in
> bar()
> }
> }
> var some: Any?
> func bar() {}
> }
> 
> ```
> 
> Forcing explicit `self` in closures on every member access introduced confusion: if it is required in closures, should I do it everywhere else? Why is it not required everywhere else?
> 
> Instead compiler should require explicit `self` in capture list, and let linter check the rest.
> 
> ### 3.3 Auto-Closure
> 
> ```swift
> class Style33a {
> let bar: Int = 42
>     
> func foo() {
> nada(bar)
> zilch(bar)
> }
> 
> func nada(_ cb: @autoclosure () -> Int) {}
> func zilch(_ cb: @escaping @autoclosure () -> Int) {}
> }
> 
> ```
> 
> > Reference to property 'bar' in closure requires explicit 'self.' to make capture semantics explicit
> 
> ```swift
> class Style33b {
> let bar: Int = 42
>     
> func foo() {
> self.nada(self.bar)
> self.zilch(self.bar)
> }
> 
> func nada(_ cb: @autoclosure () -> Int) {}
> func zilch(_ cb: @escaping @autoclosure () -> Int) {}
> }
> 
> ```
> 
> Pros of explicit `self`:
> 
> - If you miss `self`, linter warns you, forcing a review
> 
> Cons:
> 
> - Explicit `self` doesn't reveal captured `self`
> - When reading, `self.` adds noise
> - More typing
> 
> **Pitch:** Again, adding explicit `self` doesn't "make capture semantics explicit". It was a confused decision adding it to the compiler. To make it explicit, we need a different syntax, like:
> 
> ```swift
> func foo() {
> nada(bar)
> zilch([self] bar)
> }
> 
> ```
> 
> ### 3.4 Nested function
> 
> ```swift
> class Style34a {
> var bar: Int = 0
>     
> func foo() {
> func niente() {
> bar = 42
> }
>         
> nada(niente)
> zilch(niente)
> }
> 
> func nada(_ cb: () -> Void) {}
> func zilch(_ cb: @escaping () -> Void) {}
> }
> 
> ```
> 
> No compiler warnings, but `niente` captures `self`.
> 
> ```swift
> class Style34b {
> var bar: Int = 0
>     
> func foo() {
> func niente() {
> self.bar = 42
> }
>         
> self.nada(niente)
> self.zilch(niente)
> }
> 
> func nada(_ cb: () -> Void) {}
> func zilch(_ cb: @escaping () -> Void) {}
> }
> 
> ```
> 
> Pros of explicit `self`:
> 
> - If you miss `self`, linter warns you, forcing a review
> 
> Cons:
> 
> - Explicit `self` doesn't reveal captured `self`
> - When reading, `self.` adds noise
> - More typing
> 
> Alternatives:
> 
> - Replace nested function with a closure
> 
> **Pitch:** Compiler should warn you of captured `self`, and suggest using a closure with capture list. Or have an extended syntax for nested functions with a capture list, like:
> 
> ```swift
> func foo() {
> func niente() { [self] in
> bar = 42
> }
> }
> 
> ```
> 
> ### Section notes
> 
> A compiler/linter warning for a missed `self` is not to be blindly "fixed" by adding `self`, it is an opportunity to review that line. So if you type explicit `self` everywhere, there will be less compiler/linter warnings, triggering less reviews. Explicit `self` does not mean you have reviewed that line for captured `self`.

## 4. Improve readability

> ****
>
> ### 4.1 Explicit self always
> 
> ```swift
> class Style41a {
> var bar: Int = 2
> var nada: Int = 3
> 
> var baz: Int {
> return bar + nada
> }
>     
> func foo() {
> bar = baz + nada
> }
> }
> 
> ```
> 
> ```swift
> class Style41b {
> var bar: Int = 2
> var nada: Int = 3
> 
> var baz: Int {
> return self.bar + self.nada
> }
>     
> func foo() {
> self.bar = self.baz + self.nada
> }
> }
> 
> ```
> 
> Pros of explicit `self`:
> 
> - Easier to reason, you can always tell when it refers to instance member
> 
> Cons:
> 
> - When reading, `self.` adds noise
> - More typing
> 
> ### 4.2 Always self in initializers
> 
> Given the common initializer scenario, prefer explicit self on every instance reference in initializer.
> 
> ```swift
> class Style42a {
> init(bar: Int) {
> self.bar = bar
> nada = 42
> }
>     
> let bar: Int
> let nada: Int
> }
> 
> ```
> 
> ```swift
> class Style42b {
> init(bar: Int) {
> self.bar = bar
> self.nada = 42
> }
>     
> let bar: Int
> let nada: Int
> }
> 
> ```
> 
> Pros of explicit `self`:
> 
> - Easier to reason, you can always tell when it refers to instance member
> - Uniform style easier to read
> 
> Cons:
> 
> - When reading, `self.` adds noise
> - More typing

## IDE Support

> ****
>
> #### Highlight selected symbol
> 
> This is very useful, but relies on lexical scope, thus beyond simple text editors.
> 
> ![selected symbol|](https://global.discourse-cdn.com/swift/original/2X/5/5440a6315e3e1b8a0b0446b360e4e7a32ba4df9e.gif)
> 
> #### Syntax highlighting
> 
> Have different style for instance and non-instance variables. This relies on lexical scope.
> 
> ![syntax highlight](https://global.discourse-cdn.com/swift/original/2X/7/778bbbf858d7a9e700a73c98fcd05f890fa17bc0.png)
> 
> #### Notify of added/removed shadowing
> 
> **Pitch:** IDE could notify you with a confirmation dialog, or a less intrusive inline warning, or a short-lived highlight.

## Discussions

> ****
>
> - [SE-0009 Require self for accessing instance members](https://github.com/apple/swift-evolution/blob/master/proposals/0009-require-self-for-accessing-instance-members.md)
> - [[Rejected] SE-0009 Require self for accessing instance members](https://forums.swift.org/t/rejected-se-0009-require-self-for-accessing-instance-members/930)
> - [SwiftLint: Enforce explicit self](https://github.com/realm/SwiftLint/issues/321)
> - [Proposal: Re-instate mandatory self for accessing instance properties and functions (David Hart)](https://forums.swift.org/t/proposal-re-instate-mandatory-self-for-accessing-instance-properties-and-functions-david-hart/179)
> - [Proposal: Re-instate mandatory self for accessing instance properties and functions](https://forums.swift.org/t/proposal-re-instate-mandatory-self-for-accessing-instance-properties-and-functions/486)
> - [Proposal: Allow `[strong self]` capture in closures and remove the `self` requirement therein](https://forums.swift.org/t/proposal-allow-strong-self-capture-in-closures-and-remove-the-self-requirement-therein/551)
> - [[Review] Require self for accessing instance members](https://forums.swift.org/t/review-require-self-for-accessing-instance-members/562)
> - [Proposal SE-0009 Reconsideration](https://forums.swift.org/t/proposal-se-0009-reconsideration/2668)
> - [Should explicit `self.` be required when providing method as closure?](https://forums.swift.org/t/should-explicit-self-be-required-when-providing-method-as-closure/5357)
> - [[Pitch] Improving capturing semantics of local functions](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054)
> - [Explicit capture semantics applied too broadly?](https://forums.swift.org/t/explicit-capture-semantics-applied-too-broadly/11737)
> - [Revisiting requiring explicit `self.` when passing a method as an escaping closure](https://forums.swift.org/t/revisiting-requiring-explicit-self-when-passing-a-method-as-an-escaping-closure/12149)
> - [Pitch: Weak method storage modifiers (aka weak references)](https://forums.swift.org/t/pitch-weak-method-storage-modifiers-aka-weak-references/12161)
> - [Request explicit capture of self instead of defaulting to a strong capture of self](https://forums.swift.org/t/request-explicit-capture-of-self-instead-of-defaulting-to-a-strong-capture-of-self/13678)
> - [Implicit retain cycle](https://forums.swift.org/t/implicit-retain-cycle/15238)

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 4, 2019, 1:41am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/2 "2019-03-04T01:41:01Z")

</div>

> [@paiv](#):
>
> There is only one case where you are _required_ to write explicit `self` – to refer to a member shadowed by another variable.

There's a second case: when referring to a property or method of `self` inside an escaping closure.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 1:58am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/3 "2019-03-04T01:58:31Z")

</div>

I've stated my case about closures in 3.2

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 4, 2019, 2:04am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/4 "2019-03-04T02:04:50Z")

</div>

I actually didn’t realize that putting an implicitly strong `self` in the capture list would also suppress the warning! I’d be surprised if this is widely known since I don’t believe I’ve ever seen it in Swift code in the wild. (Indeed, capture lists in general aside from `weak/unowned self` tend to be uncommon.)

If you want that pattern to take off, I think you’d want more than just the linter involved here; the compiler diagnostics heavily encourage users to write explicit `self.` member references instead.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 2:08am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/5 "2019-03-04T02:08:12Z")

</div>

That's why it is marked with `Pitch` – to change today's views and update compiler implementation.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 4, 2019, 2:11am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/6 "2019-03-04T02:11:13Z")

</div>

Ah, that’s why I was confused—you may want to move this to Evolution \> Pitches. As it is right now, it’s labeled “[Style]” and in the Using Swift forum so it looks like you’re merely debating style issues.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 2:16am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/7 "2019-03-04T02:16:32Z")

</div>

This is to debate style issues. I haven't seen strong argument for explicit self yet. I'm uncovering compiler issues along the way.

---

<div class="post-metadata">

**Author:** ![matux](https://avatars.discourse-cdn.com/v4/letter/m/7cd45c/32.png) [@matux](https://forums.swift.org/u/matux)\
**Post date:** [March 4, 2019, 4:07am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/8 "2019-03-04T04:07:27Z")

</div>

Repetition forms habit, my nana used to say.

Whether it is writing code or reading it, repetition taps into the procedural memory mechanism of your brain becoming unconscious. Sooner or later, you'll become unaware that "self" is even there. This can be a great thing or the exact opposite of what you want.

There's something very cool about procedural memory: If instead of mechanical, the repetition is fueled by willingness, reasoning and fun, it forms intuition.

The goal, then, is to make complex semantics simple enough that a programmer will be willing (eager even) to reason about complex problems and develop intuition, instead of doing whatever the compiler tells you to do to make your thing work, and end up developing a mechanical habit.

A compiler who has to remind intermediate/veteran Swift programmers of a missing `self.` or a missing `@escaping`, or whatever, is a problem in the language. I see this happen all the time. To coworkers, to friends and to my face. And the response to it never is "Phew!", it is "Ugh." (sometimes followed by a random expletive.)

• **The optionality of `self` is what the problem is.**

It introduces semantic ambiguity between a complex subject you don't face often (memory management in ARC), and a very simple and familiar one ("reaching a member of an object").

As much as I love Swift, this is kind of a major "wat" to me.

Especially if you're a newcomer trying something inane like updating a label inside an async closure: "Implicit use of self, use self to make closure capture semantics expli" huh? what? wait, there's a fix it button. Whatever, _fix it._

This almost guarantees users won't even understand why they should reason about what this is about. It's a nuisance. Even worse, some could end up forming a habit of ignoring the problem till they can feel it's fangs in their butt cheeks.

**Two (hopefully) solutions are:**

1. Do the exact opposite: Disallow the usage of `self.` everywhere it's optional except when it is obligatory. This would make the semantics around it a bit more explicit, without making it repetitive enough as to end up becoming ignored noise.

2. Explicit ownership semantics ala Rust. Which is the current direction in which Swift is headed, as far as I can remember from [https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md](https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md). And the best answer we have to this problem so far, in my arrogant opinion.

Btw, code that is easier to reason and code with bad noise to signal ratio is a dichotomy.

---

<div class="post-metadata">

**Author:** ![TellowKrinkle](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tellowkrinkle/32/3370_2.png) [@TellowKrinkle](https://forums.swift.org/u/TellowKrinkle)\
**Post date:** [March 4, 2019, 7:30am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/9 "2019-03-04T07:30:30Z")

</div>

I don't think we should increase the amount of required explicit `self`. I would be in favor of allowing `[self]` capture lists to remove the need to use explicit self within a closure.

I do like a lot of the possible IDE feature ideas though, a highlight flash of all the variables whose references were just changed by a paste, comment, or deletion would be great.

I also think a special case compiler warning that catches assigning self-capturing closures or functions to ivars might be helpful, though it might be good to first search through a bunch of existing Swift code to find cases where someone uses it but it's actually okay (gets reassigned afterwards) to see if that's something commonly done (I would think not but who knows).

I also agree that more explicit ownership would be one of the best solutions to this, one of my biggest annoyances with the explicit self rules is if you try to do something like this and have to use explicit self because the compiler doesn't notice that your closures don't live beyond the line:

```swift
let thing = Array(collection.lazy.filter{ $0 < self.a }.map{ $0 * self.b })

```

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [March 4, 2019, 9:08pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/10 "2019-03-04T21:08:09Z")

</div>

Yes, please. Explicit `self.` is in my opinion very incredibly important because otherwise I find it nearly impossible to code-review. I understand we can’t change the language to require it but it should definitely be at least recommended. How else can I know from a GitHub diff is something’s a property access or not?

The “`self.` becomes noise” argument I really can’t follow. I use `self.` as a search term in Xcode and I explicitly look for `self.` in code reviews. In SwiftNIO explicit `self.` is required as a coding standard (not yet enforced sadly) so I can be reasonably sure I don’t miss anything but I’d like to 100% sure.

The pitch describes the reasons for explicit `self.` very well. I want to add that local reasoning is very important and having explicit `self.` makes that possible because it’s a signal that we can no longer reason locally, everything that uses `self.` affects more than just the local function. Also: in complex library/framework code it’s often important to know when state is reconciled because if there’s any potential for re-entrancy, state needs to be reconciled before calling out to the user (as the user might re-enter the same method). I think a very high number of SwiftNIO bugs happened because we called into user code before reconciling state on some object. And state modification on an object is much easier spotted when `self.` is explicit. All assignments that aren’t to `self.xyz` are mostly local variables and hence much less dangerous.

Today my strategy often is to make a given part of a method temporarily a `static func` which requires me to list all the “inputs” explicitly as function parameters, all that just to be sure nothing uses `self.` without me noticing...

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [March 4, 2019, 9:59pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/11 "2019-03-04T21:59:11Z")

</div>

> [@johannesweiss](#):
>
> The “ `self.` becomes noise” argument I really can’t follow. I use `self.` as a search term in Xcode and I explicitly look for `self.` in code reviews. In SwiftNIO explicit `self.` is required as a coding standard (not yet enforced sadly) so I can be reasonably sure I don’t miss anything but I’d like to 100% sure.

@matux's [post](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/8) is a good argument as to why it's noise: if it's always there then the user reading the code has no idea when it's actually important. Most of the time with local state like that it doesn't really matter where the value comes from, since you really only have two possibilities: local, which should be visible; and instance, and it should clear from context that it's not local. However, in some cases I guess, like SwiftNIO, it might be important given the fragility of local state. Which is why it should probably be a configurable part of a built in formatter.

In general explicit `self` seems a lot like explicit `strong` in Obj-C properties: as the default, it can serve to illustrate that "this is the default" but really is just noise since nearly everything uses the default value.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 10:24pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/12 "2019-03-04T22:24:07Z")

</div>

> [@johannesweiss](#):
>
> How else can I know from a GitHub diff is something’s a property access or not?

If you are reviewing logic, look at the whole context, review full function body, not only the changes introduced.

On the project as fundamental as NIO, I'd expect TDD style, and more focus on tests.

---

<div class="post-metadata">

**Author:** ![svanimpe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/svanimpe/32/38963_2.png) [@svanimpe](https://forums.swift.org/u/svanimpe)\
**Post date:** [March 4, 2019, 10:24pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/13 "2019-03-04T22:24:20Z")

</div>

> [@johannesweiss](#):
>
> The “ `self.` becomes noise” argument I really can’t follow.

A simple type, without explicit self:

```swift
struct Vector {

  var x: Double
  var y: Double

  var length: Double {
    get {
      return sqrt(x * x + y * y)
    }
    set {
      x = (x / length) * newValue
      y = (y / length) * newValue
    }
  }
}

```

With explicit self:

```swift
struct Vector {

  var x: Double
  var y: Double

  var length: Double {
    get {
      return sqrt(self.x * self.x + self.y * self.y)
    }
    set {
      self.x = (self.x / self.length) * newValue
      self.y = (self.y / self.length) * newValue
    }
  }
}

```

For me, the second version is unreadable :( Perhaps it's the repetition, or that `self` is a reserved word and therefor highlighted, but the only information that reaches my brain after scanning that code is "self self self self self ...". Reading the second version for me is like trying to talk to someone while someone else is yelling in your face.

I assume I'm not a special snowflake and that many others have the same issue.

I really hope this discussion won't be reopened and that [the rationale for rejecting SE-9](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005478.html) applies to the style guide as well.

---

<div class="post-metadata">

**Author:** ![phoneyDev](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@phoneyDev](https://forums.swift.org/u/phoneyDev)\
**Post date:** [March 5, 2019, 1:24am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/14 "2019-03-05T01:24:02Z")

</div>

To me **self.** used when not required is definitely noise. Code readability has become a pet peeve of mine in recent years. I don't like long methods. I don't like a bunch of boiler plate code in a large method that should be tucked away in short one-purpose methods I don't like unclear variable names and I don't like reading anything that isn't required to understand the code. I place unnecessary **self.** in the category of something extra to read that provides me no additional semantic meaning.

The usual response to using **self.** to mark ivar usage is that if you can't tell if a variable is local or an ivar then your code has bigger problems.

The one case I'm on the fence about a little is marking usage of inherited ivars. If you press me I'll say don't do it but I kind of understand why some people do it.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 5, 2019, 6:56am UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/15 "2019-03-05T06:56:03Z")

</div>

> [@johannesweiss](#):
>
> How else can I know from a GitHub diff is something’s a property access or not?

In case others missed it, GitHub lets you expand context in diffs:

 ![expand](https://global.discourse-cdn.com/swift/original/2X/4/485e94673c65cfac39bf8263e41da6209801e217.png)

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [March 5, 2019, 2:16pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/16 "2019-03-05T14:16:10Z")

</div>

> [@Jon\_Shier](#):
>
> @matux's [post](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/8) is a good argument as to why it's noise: if it's always there then the user reading the code has no idea when it's actually important.

But to a reviewer on GitHub without the explicit `self.` it's unclear. Also as I pointed out: You can search for `self.` but you can't if omitted.

> [@Jon\_Shier](#):
>
> Most of the time with local state like that it doesn't really matter where the value comes from, since you really only have two possibilities: local, which should be visible; and instance, and it should clear from context that it's not local.

But in multi-threaded and re-entrant code, instance properties might change whilst you're in some local scope, so personally everything that's an instance variable always reads like 'danger here' to me but only if I can actually see it (`self.`).

Maybe it's because I don't work on UI heavy code bases, maybe `self.` is much more common in every other line there?

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [March 5, 2019, 2:17pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/17 "2019-03-05T14:17:24Z")

</div>

> [@paiv](#):
>
> > How else can I know from a GitHub diff is something’s a property access or not?
> 
> In case others missed it, GitHub lets you expand context in diffs:

There's a lot of expanding to do there but most importantly it's so easy to miss an instance variable access lacking the `self.`.

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [March 5, 2019, 2:45pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/18 "2019-03-05T14:45:12Z")

</div>

> [@paiv](#):
>
> If you are reviewing logic, look at the whole context, review full function body, not only the changes introduced.
> 
> On the project as fundamental as NIO, I'd expect TDD style, and more focus on tests.

That's exactly what we do, I would consider NIO very well unit-tested but make yourself an opinion. We consider unit tests to be incredibly important and we won't merge without decent tests. However tests and TDD only gets you so far. Even 100% test coverage means very little in reality as with concurrent and re-entrant code lots of state can change in lots of places, very often without you expecting that to happen.

For example take this silly piece of code (totally made up):

```swift
class FileOpener {
    var fileDescriptor = Int?
    weak var delegate: FileOpenerDelegate? = nil

    func openFile() throws {
        guard self.fileDescriptor == nil else {
            return
        }
        if let fd = open(....) // actually open the file {
            self.delegate?.fileOpener(self, didOpenFile: ...)
            self.fileDescriptor = fd
        }
    }

    func closeFile() throws { ... }
}

```

looks pretty harmless, getting 100% test coverage trivial but you'd still likely miss an important but subtle bug: `self.fileDescriptor = fd` is done too late (after calling out). If the `self.delegate?.fileOpener(..., didOpenFile: ...)` happens to somehow call `openFile` on the same object again, you're in trouble because `self.fileDescriptor` is still `nil` (but it shouldn't) and we'd open the file again, leaking a file descriptor.

The way I'd review code like this is to find the callouts (search for `self.delegate.`) and look if there's any state possibly modified after a callout has been done (search for `self\..* = ` in the lines following `self.delegate.`). If there's any such modification after the callout, then very likely we have a bug here. Quite straightforward in a review with `self.`, very hard to do without...

Testing all the various situations is usually impossible because there's infinitely many things that can be done during a callout so you can't just test for everything that might happen.

* * *

> [@svanimpe](#):
>
> For me, the second version is unreadable :( Perhaps it's the repetition, or that `self` is a reserved word and therefor highlighted, but the only information that reaches my brain after scanning that code is "self self self self self ...". Reading the second version for me is like trying to talk to someone while someone else is yelling in your face.

Interestingly, the 'yelling in the face' is exactly what I want. In your particular example: It's a value type that doesn't call out, the 'yelling in the face' in indeed just noise as the properties can't change 'under the hood' because `mutating` functions in `struct`s own the struct exclusively and if you violate it, [Swift will crash the program](https://swift.org/blog/swift-5-exclusivity/) for you.

For everything that's a reference type (`class`) though or code that calls out to the user, or maybe passed `self` as an `inout`, then I believe you really need the 'yelling in the face' to call out a property access as what it is: a side-effect which might get you different data from last time you used that variable, often the source of [TOCTOU](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use) security vulnerabilities.

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [March 5, 2019, 2:59pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/19 "2019-03-05T14:59:12Z")

</div>

These are really interesting code review stories. I see and understand how "mechanical" checks, purely based on syntax, can help. I pretty much like syntax-based safety myself, because it avoids needless thinking. Thanks for taking the time to share your techniques.

Now, may I suggest a solution that would please everybody? Not really in the context of this thread, because it talks about "recommended practices" which are highly subjective, as we can see, and quite unlikely to settle on a one-size-fits-all conclusion, but in the context of the current [Standard Style Guide and Formatter](https://forums.swift.org/t/pitch-an-official-style-guide-and-formatter-for-swift/21025) thread:

**When reformatting, preserve existing `self.`**

This would allow your team's practices to keep on flying.

This would also leave all those pieces of code intact:

```swift
init(area: Int) {
    // Can't avoid `self.`
    self.area = area
}

init(width: Int, height: Int) {
    // My team doesn't want `self.`
    area = width * height
}

init(width: Int, height: Int) {
    // My team wants `self.`
    self.area = width * height
}

```

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [March 5, 2019, 3:01pm UTC](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173/20 "2019-03-05T15:01:19Z")

</div>

> [@gwendal.roue](#):
>
> **When reformatting, preserve existing `self.`**
> 
> This would allow your team's practices to keep on flying.

👍, probably the only viable solution. There can also be more than one tool: A code formatter without configuration (like `go-fmt`) that does indentation, spacing, etc and a code linter that has configuration and checks things like explicit `self.`.

[Next page](https://forums.swift.org/t/style-explicit-self-when-referencing-instance-member/21173.md?page=2)
