[swift-evolution] Proposal: Closures capture weak by default

Joe Groff jgroff at apple.com
Tue Dec 8 12:51:10 CST 2015


> On Dec 8, 2015, at 10:48 AM, Gwendal Roué <gwendal.roue at gmail.com> wrote:
> 
>>> I’m really not found at all of having `let` properties captured by closures when used without explicit `self`.
>>> 
>>> Three reasons […]
>>> 
>>> REASON 2. What happens when a property starts its life as `let`, but turns `var` eventually? For example, the property eventually becomes lazy. OK now it’s is illegal to use the property without explicit `self` in closures, and you break a bunch of code. And you need to bump the major version of your package. Just because you turn a `let foo: String` into `lazy var foo: String = …`.
>>> 
>>> That’s not good at all.
>> 
>> These are good points, but re: reason 2, turning a public 'let' into a 'var' is already a non-resilient, semantics-breaking change, since you're taking back a promise you made about immutability. You should publish a public 'var' with a private setter if you want to reserve the right to publish mutability in the future.
> 
> Is it so sure? I don’t see any difference, API-wise, between `let foo` and `lazy var foo`. Maybe I forgot the private(set), but in this case please be nice and follow me: I’m talking about a public getter that starts its life as `let` and ends its life as `lazy var`. There is no API difference in this case, and no reason to bump the major version of a package that would expose such a getter.
> 
> Besides, a non-lazy property that starts its life as `let foo` and ends as `private(set) var foo` is in the same category: there is *no* difference in the public API, and *no* reason for bumping the major version of the lib.

There *is* an important difference in API between "nobody can mutate this" and "you can't mutate this, but others may be able to." The former is a much stronger guarantee that can't be safely weakened without breaking code.

-Joe




More information about the swift-evolution mailing list