I’m a +1 for making the behaviour more consistent, I can’t imagine many people 
rely on the guaranteed execution for static properties (personally I wasn’t 
even aware there was a difference), and anyone that needs guaranteed execution 
should be implementing lazy properties manually (i.e- with computed properties) 
as it’s possible to trigger required code more efficiently that way.

So yeah, I think that execution only as required is the right choice and that 
these should definitely be made consistent.

> On 31 May 2016, at 14:32, David Rönnqvist via swift-evolution 
> <[email protected]> wrote:
> 
> With the risk of this showing up 3 times in the mailing list (I posted it as 
> a new topic, but it didn't seem to show up).
> 
> 
> Several weeks ago I posted that I was confused by the differences between how 
> static variables and lazy variables evaluated (or - as I would expect - 
> didn’t evaluate) when initially assigned with a different value. It didn’t 
> result in any discussion, but I encountered it again and decided to draft a 
> proposal hoping that there will be some discussion around it. The draft is 
> available here: 
> https://github.com/d-ronnqvist/swift-evolution/blob/master/proposals/0000-static-var-lazy-behavior.md
>  
> <https://github.com/d-ronnqvist/swift-evolution/blob/master/proposals/0000-static-var-lazy-behavior.md>
> 
> Please let me know what you think, and if you believe this is something 
> that’s worth pursuing.
> 
> - David
> 
> 
> Lazy evaluation when assigning static variables
> 
> Proposal: SE-NNNN 
> <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
> Author(s): David Rönnqvist <https://github.com/d-ronnqvist>
> Status: Awaiting review 
> <https://github.com/d-ronnqvist/swift-evolution#rationale>
> Review manager: TBD
>  <https://github.com/d-ronnqvist/swift-evolution#introduction>Introduction
> 
> Both stored type properties (static) and lazy stored properties (lazy var) 
> are lazily initialized. However, they have different initialization behavior 
> in that stored type properties evaluate even when assigning them a new value.
> 
> The following code will print "static", but not "lazy":
> 
> class Foo {
>     static var bar: String = {
>         print("static")
>         return "Default"
>     }()
> 
>     lazy var baz: String = {
>         print("lazy")
>         return "Lazy"
>     }()
> }
> 
> Foo.bar = "Set" // this evaluates the initial value of `bar` before setting a 
> new value
> 
> let foo = Foo()
> foo.baz = "Set" // this doesn't evaluate `baz` before setting a new value
> Swift-evolution thread: [Discussion] Difference between static and lazy 
> variables regarding evaluation of closure 
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/14086>
>  <https://github.com/d-ronnqvist/swift-evolution#motivation>Motivation
> 
> Swift currently evaluates stored type properties even when assigning a new 
> value. This behavior is very subtle and can lead to objects being needlessly 
> initialized and "immediately" de-initialized, as well as unwanted side 
> effects (caused by the initialized objects).
> 
> For example, a shared re-assignable instance that is replaced during unit 
> test set up will initialize the "real" object before assigning the test 
> replacement. 
> 
>  <https://github.com/d-ronnqvist/swift-evolution#detailed-design>Detailed 
> design
> 
> This proposal seeks to unify the lazy evaluation on assignment of stored type 
> properties (static) and lazy stored properties (lazy var) so that the value 
> being replaced isn't evaluated (the current behavior of lazy stored 
> properties). 
> 
> However, it seeks to keep their respective behaviors and guarantees regarding 
> multithreaded simultaneous access:
> 
> From the The Swift Programming Language (Swift 2.2) 
> <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID254>
>  regarding lazy stored properties: 
> 
> If a property marked with the lazy modifier is accessed by multiple threads 
> simultaneously and the property has not yet been initialized, there is no 
> guarantee that the property will be initialized only once.
> and regarding stored type properties:
> 
> Stored type properties are lazily initialized on their first access. They are 
> guaranteed to be initialized only once, even when accessed by multiple 
> threads simultaneously, and they do not need to be marked with the lazy 
> modifier.
> No changes to the syntax is proposed. 
> 
> This provides a more consistent lazy evaluation behavior, and fixes a (small) 
> source of potential, subtle bugs.
> 
>  
> <https://github.com/d-ronnqvist/swift-evolution#impact-on-existing-code>Impact
>  on existing code
> 
> This proposal changes the lazy evaluation of stored type properties when 
> assigning a new value. 
> 
> Any code that is relying on this effect would break in subtle ways. This is 
> hard to detect and migrate, but hopefully very rare (and to the best of my 
> knowledge the behavior that code would be relying upon is undocumented).
> 
>  
> <https://github.com/d-ronnqvist/swift-evolution#alternatives-considered>Alternatives
>  considered
> 
> One alternative is to be consistent with the stored type properties and 
> always evaluate the initial value, even when re-assigning it. However, this 
> version doesn't address the subtle bugs that can arise from this behavior.
> 
> Another alternative is to leave the the respective behaviors as is and 
> mention their differences in The Swift Programming Language guide. This might 
> still be the most viable alternative in case the current behavior is a 
> consequence of their respective implementations with regards to multithreaded 
> access.
> 
>  <https://github.com/d-ronnqvist/swift-evolution#rationale>Rationale
> 
> On [Date], the core team decided to (TBD) this proposal. When the core team 
> makes a decision regarding this proposal, their rationale for the decision 
> will be written here.
> 
> 
> 
> 8 apr. 2016 kl. 18:50 skrev Vladimir.S via swift-evolution 
> <[email protected] <mailto:[email protected]>>:
> 
>> Yes, IMO it really looks strange.
>> Just checked:
>> 
>>    class Foo {
>>        static var test = "test"
>> 
>>        static var bar: String = {
>>            print("static")
>>            return "Default"
>>        }()
>> 
>>        lazy var baz: String = {
>>            print("lazy")
>>            return "Lazy"
>>        }()
>>    }
>> 
>> 
>>    print("1")
>>    print(Foo.test)
>>    print("2")
>>    Foo.bar = "Set"
>>    print("3")
>>    let foo = Foo()
>>    foo.baz = "Set"
>>    print("4")
>> 
>> we have :
>> 1
>> test
>> 2
>> static
>> 3
>> 4
>> 
>> I strongly believe as static property is lazy by definition, it must not be 
>> evaluated at all when we set it. This is something that "lazyness" promises 
>> to us - that it will be called/calculated ONLY when we ask for this. So in 
>> my opinion this is bug/issue and should be fixed/changed in Swift 3.0.
>> 
>> 
>> On 08.04.2016 10:36, David Rönnqvist via swift-evolution wrote:
>>> I noticed a difference between how static and lazy variables evaluate 
>>> closures and thought that it was a bug:
>>> https://bugs.swift.org/browse/SR-1178 
>>> <https://bugs.swift.org/browse/SR-1178>
>>> but apparently it’s not.
>> > ...
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to