SE-0481: `weak let`

Thank you, that answers my questions :+1:

To me, the introduction of a new language construct and changing the behavior of closures seem like two separate parts of this proposal, that could be split into 2 proposals if needed.

I'm going to say +1 on the immutable weak captures. It's surprising to me that there was a condition where changing a variable inside a capture list is possible, and it's not obvious how this would affect subsequent calls of the closure (is it always nil or is it back to default on the next call?). In either case, assigning nil to a weak capture can never lead to an object being released (same with assigning nil to a weak var) but it could possibly shadow an intended call to a strong var, which means that users may think they're releasing a reference.

I'm not opposed to weak let, but I hope this gap in Sendable closures can be closed regardless of the new construct being accepted.

weak let declarations are a dependency for immutable closure captures. Explicit closure captures are actually variable declarations. To have immutable weak capture compiler needs to be able to create immutable weak variable.

It is not impossible to handle closure captures and regular variables differently, but keeping them consistent makes things simpler both for language users and compiler implementation.

2 Likes

Seeing
return { [weak c] in
makes me think: Wouldn't it be possible to omit the let in the declaration as well?
Afaics, weak ref1: C? could at least be an alternative worth mention.

The mental model that I've been using to describe the difference between a read-only var declaration from a let declaration suggests that:

  • A read-only β€˜var` declaration uses the default property declaration keyword that that is used in almost every situation (see the one notable exception below). The keyword itself has no baring on mutability and the fact that it seems to be a contraction of the word "variable", implying change, is merely an unfortunate historical side-effect, remedying of which seems next to impossible.
  • Alet declaration is the one special case, denoting a property that is backed by immutable memory with no executable code associated with its access. Because of this multi-sided limitation (backed by memory, immutability, and no custom access), the compiler is free to optimize the property more aggressively and can even relocate it into read-only memory, when appropriate.

As was explained to me before, an expired weak variable isn't set to nil, so much as it's marked as expired and the compiler-generated getter merely checks for that condition, returning nil if that's the case.

This contradicts my mental model by having a getter involved in a let, but my explanation of this is as follows:
A weak var doesn't have a user-visible getter, which makes it look like a stored property that is being assigned a nil value.
This proposal is focused more on the functional limitation of current weak var declarations (always being user-resettable) and given the existing syntax, using let to denote a weak property that cannot be changed must've seemed like the least disadvantageous option.

Maybe my mental model is lacking (I'd love to see alternative mental models for this), but regardless of this seeming conceptual discrepancy, given how much difficulty I've experienced from the lack of this feature, its benefits far outweigh the downside of violating the meaning of let (again, my mental model could be wrong, please correct it if you think so).

2 Likes

One other small point:

A programmer is currently required to use weak var (instead of weak let). Because of that, they are also free to add willSet or didSet observers to that var. Because of that, it would be reasonable to assume that those observers would be called when the value becomes nil.

The Swift Programming Language contains a note just to cover this:

Note
Property observers aren’t called when ARC sets a weak reference to nil.

Assuming that weak let does not allow property observers, I think that makes it a better fit.

9 Likes

SE-0481 has been accepted. Thank you, everyone, for contributing to this review.

John McCall
Review Manager

5 Likes