[Syntax] Default name for optional binding self and other properties

Introduction

Optional binding is one of the most popular ways to unwrap an optional value. Moreover, when the optional is in the current scope, like self, it's standard practice to initialize the bound constant with the same name. Consider the following very common scenario occurring inside closures that weakly capture self:

guard let self = self else {
    return
}

Proposed solution

Because this approach is so popular I propose to introduce the option to omit the assignment and implicitly use the same name:

guard let self else {
    return
}

This behavior would obviously extend to other control flow statements:

if let error {
    preconditionFailure(error.localizedDescription)
}

Motivation

This would enforce good practice by default. Using a different name, like strongSelf adds unnecessary complexity in my opinion. In the spirit of progressive disclosure, customizing the name of the bound constant could be considered an advanced feature that novice language users don't have to know about when getting started.

Inspiration

Capture lists follow the same implicit naming pattern:

[weak self = self]

Personally, because I encounter the weak self dance so frequently, this change would make code simpler to read and reason about. What do you think?

14 Likes

This has been discussed many times in the past:

  1. Easy strongified weak `self` in closures
  2. Syntactic sugar for simplifying guards
  3. Pitch: Syntactic sugar for circumventing closure capture lists
  4. Proposal: weakStrong self in completion handler closures
  5. [Proposal Update 1] A simplified notation for avoiding the weak/strong dance with closure capture lists

IMHO it's not worth adding complexity to the language to save a few keystrokes in this scenario. The fact that you have to explicitly do this "dance" is for a good reason (clarity over terseness, which is important when dealing with weak/strong references).

10 Likes

I've been quietly hoping for a long time that we would eventually come around to this. I think it comes up a lot because it's a common pain point -- I know that I write if let x = x and guard let x = x all the time, and I always find it tedious. The main argument against the proposal as I understand it is that the proposed syntax lacks clarity, but I really don't find that to be true. It seems perfectly reasonable and clear to me.

Has this ever made it beyond the pitch phase? I'd really like to see it go through the full proposal process and get the core team to weigh in.

2 Likes

Does it extend to var too?

if var error { ... }

(The current syntax works with var.)

tt should!

Yeah, I do this all the time. It reminds me a bit of the idea of having the automatically synthesized newValue in a didSet. It seems to have merit for me to save keystrokes and is clear what you’re doing. I’m usually for clarity over brevity but the duplication of the property name doesn’t really do anything for clarity IMHO.

8 Likes