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
