[swift-evolution] Proposal: Closures capture weak by default
gwendal.roue at gmail.com
Tue Dec 8 12:56:59 CST 2015
> Le 8 déc. 2015 à 19:51, Joe Groff <jgroff at apple.com> a écrit :
>> 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.
This is true, you are right. The property could be mutated by the package internals.
This paves the way for another swift evolution request, actually. The `var` in lazy and the `private(set)` are often plasters on properties that are *intended* to be immutable, but can not be because of the current limitations of the language.
More information about the swift-evolution