The Future Of [weak self] Rebinding

What would [guard self] do when the closure returns some value and not Void?


Thank you for bringing this up, and you are right that time does change things. To be completely clear, I am speaking only for myself in this post, not the core team or anyone else.

A couple of years ago, I was completely against anything like this, feeling strongly that ‘self’ as a keyword was magical and privileged. Various things have changed that opinion, including the introduction of guard.

I now agree with you that this is important, and that we should do the obvious thing here: just make self be a normal identifier which is implicitly injected into methods. This is your #1 option, which would allow rebinding with if/let, guard, shadowing and everything else.

I am pretty strongly opposed to #2 (make the bug a feature) as the bug is an ugly gross workaround. We should just move forward and accept the obvious code that users will continue to write. I don’t see any obvious downside of doing so.



Good question – I think it would have to be forbidden in that case. In my personal experience, the types of closures that I use [weak self] in are almost (maybe entirely) exclusively callback-style closures that don’t return anything, so I see this as an edge case.

1 Like

I fully support this as the correct approach in general, not just a special case for closures. Still, we may support a [guard self] for closures as a sugar for the closures that have a return type of either optional or Void.


I’m also not a fan of new syntax to sugar around a single use-case. I’d go with Option #1.

1 Like

Maybe this is similar to what @anandabits has in mind, but what if instead of a sugared [guard self] construct, there was a modifier keyword used in closure capture lists to indicate that a given value needs to be guard-unwrapped? For example (strawman syntax) –

doSomething() { [required weak self] in

which would be equivalent to

doSomething() { [weak self] in
    guard let `self` = self else { return }

This could be applied to other captured values too, not just self. Any thoughts?


Should discussion of ideas like [guard self] take place in a different thread, perhaps? It’s related but still a bit of an aside from the main issue here, which is whether self should be allowed to be rebound in let/guard statements. That can be considered separately from the bug fix described in the original post and there’s a lot of bike-shedding going on that’s independent of that issue.


@allevato I think discussion of guarded closures should be moved to a separate thread. I’m out of town right now and will dig up the draft proposal I have when I get back home in a couple days. I’ll post that in a new thread for further discussion.

Even in small projects, I run into writing guard let strongSelf = self else { return } often. Supporting guard let self = self else { return } makes the most sense to me. We have not hesitated to fix bugs in the past, and here, the migration strategy is the mere removal of two characters. Deprecate the backtick-hack thingy it in Swift 4.2 or Swift 5, remove later in favour of the real logical syntax.

A possible [guard self] syntax in the capture list should be discussed independently.

1 Like

Currently, you can write let `anyIdentifier` = 1, and it's accepted. This isn't a hack, it's a general feature which allows keywords (EG: in, default) to be used as argument labels and identifiers.

Sorry, I was specifically referring to the usage of self with backticks as the ‘hack’.

Why should we disable this specifically for self, when it works with any other identifier (even when redundant)? Perhaps a warning with a fixit in the short term is sensible, but in the long term, I’m not sure why self needs special-casing like this.

PS: I agree the current behaviour is a bug/hack. I’m just wondering about your suggestion to ‘remove’ this capability once rebinding self is actually allowed.

1 Like

That’s fair. The initial post suggested a migration but like you say, it’s actually consistent with the rest of the language as is. Just supporting guard let self = self else { return } is enough, and frictionless.


Evan Maloney: Upgrade self from weak to strong

1 Like

This proposal is already merged as SE-0079 with “Deferred” status.


Thank you Chris and everyone who gave their input.

In my original post I include “having to do a migration” as a con in option 1. Luckily some of you pointed out that it’s not necessary if self is to be an identifier.

I’ve made a small change to the parser that enables option 1 and keeps the rest of the compiler behavior for now:

With this patch, self is not completely a normal identifier yet in the sense that the parser would still consider it a keyword sometimes. But it gets us closer.


I will add my :+1: for option #1 because it is what the Swift language naturally pushes developers towards.

While guard let `self` = self else { return } is considered a hack around a compiler bug, one may argue that guard let strongSelf = self else { return } is a hack around a design shortcoming in the language.

Swift is still a nascent language and hasn’t hesitated to improve support for best practices that the community has trended towards. I would love to see @anandabits’ proposal revived and this issue discussed in even greater depth.

Why not just introduce an unwrap keyword?

guard unwrap self else { ... }
if unwrap self { ... }

:point_up:️ This is what’s always made the most sense to me.

I suggest starting a separate thread for this pitch.