[swift-evolution] [Discussion] Difference between static and lazy variables regarding evaluation of closure

Joe Groff jgroff at apple.com
Tue May 31 19:20:59 CDT 2016


> On May 31, 2016, at 12:37 PM, Chris Lattner via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> On May 31, 2016, at 6:32 AM, David Rönnqvist via swift-evolution <swift-evolution at swift.org> wrote:
>> Lazy evaluation when assigning static variables
>> 
>> 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
> This seems like a step in the right direction, but may not big a step far enough.  Keep in mind that “static” and global variables are quite different than lazy variables, both in terms of implementation and behavior but also in terms of planned future direction.
> 
> “lazy” is almost certainly to be replaced by property behaviors in the future, making them a library defined feature whose behavior can be changed arbitrarily, and can hopefully have useful additional functionality like a “reset()” method added to them.  Global variables are currently not like that: their behavior is defined by compiler magic instead of by property semantics.
> 
> If the goal was to remove magic from the compiler, then a possible direction would be to do something like:
> 
> 1) Introduce a new declmodifier named something like “atomiclazy”.
> 2) Disallow global and static variables, unless they are explicitly marked atomiclazy (compiler would provide a fixit hint to suggest this).
> 3) Replace the atomiclazy magic with a property behavior when they exist.

This doesn't make sense. This "magic" is the only sensible way to initialize a global that requires dynamic initialization. Even with property behaviors, we would need to lazily apply the behavior's initialization logic to get the property into its initial state. Nonatomic lazy would be a misoptimization—it's hard to beat dispatch_once at its own game.

-Joe

> In this model, you’d presumably have the choice about atomiclazy or lazy when setting up either a static or a local property.
> 
> -Chris
> 
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list