# \[Proposal\] Threadsafe lazy vars

**URL:** <https://forums.swift.org/t/proposal-threadsafe-lazy-vars/2084>\
**Category:** Discussion\
**Created:** [April 6, 2016, 9:07pm UTC](https://forums.swift.org/t/proposal-threadsafe-lazy-vars/2084 "2016-04-06T21:07:58Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Peternell](https://avatars.discourse-cdn.com/v4/letter/m/bc79bd/32.png) [@Michael\_Peternell](https://forums.swift.org/u/Michael_Peternell)\
**Post date:** [April 6, 2016, 9:07pm UTC](https://forums.swift.org/t/proposal-threadsafe-lazy-vars/2084/1 "2016-04-06T21:07:58Z")

</div>

Hi all,

lazy vars are not threadsafe in Swift 2. I saw code that uses lazy initialization in an unsafe way that introduces race conditions so often that I would be rich by now if get a penny each time. Many people use patterns like { if(\_var == nil) { \_var = [self \_calculateVar]; } return \_var; } or they just dispatch\_once, but forget that they are in an instance method, and that it will all break if there is ever more than one instance of that class.

I propose to make lazy vars atomic. Optionally, the old lazy var behavior could be renamed to something like lazy\_nonatomic.

I want to list some pros and cons for making lazy vars threadsafe:

Pros:  
- This proposal will not change the behavior of programs which are free from data races. I could argue that the change is therefore backwards-compatible.  
- I would say that programs which require lazy vars to be nonatomic in order to function correctly, are really bad style; threadsafe lazy vars behave much more deterministic. Many programs which use lazy vars incorrectly could suddenly become safe if this proposal is implemented.  
- The overhead would be minimal. For example, suppose we have a lazy var of type `NSImage`. We could represent that variable as a simple pointer which is initialized to NULL. The access could look something like this (this is just an example, there may be even more efficient solutions): {  
&nbsp;&nbsp;&nbsp;&nbsp;// we need to make sure that reads on \_var are not cached:  
&nbsp;&nbsp;&nbsp;&nbsp;memory\_read\_barrier(&\_var);  
&nbsp;&nbsp;&nbsp;&nbsp;// ^^and I'm not 100% sure that we really need that memory barrier.  
&nbsp;&nbsp;&nbsp;&nbsp;// (at least it's not needed for static vars, as proven by the implementation of dispatch\_once())

&nbsp;&nbsp;&nbsp;&nbsp;if(\_var == nil) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@synchronized(&\_var) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// ^^we synchronize on &\_var, and not on \_var  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// this is semantically invalid in objc, but the objc-runtime supports it.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// The point I want to make is that we don't need extra storage for the  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// synchronization, in many cases.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(\_var != nil) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \_var;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... some code that initializes \_var  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//@synchronized() already employs memory barriers, so no additional barriers are needed  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//maybe we should use a non-recursive lock though..  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;return \_var;  
}  
- Currently, if you need threadsafety, you cannot use lazy. You can of course wrap a lock around a nonatomic lazy var, but that would be much more inefficient than a native implementation.  
- I guess, no one will really complain if lazy var's are suddenly threadsafe. I also cannot see how it would break any code (except for contrived examples.)  
- In some cases, the nonatomic behavior can be used as an optimization, if it is semantically equivalent. For example, a lazy var that lives in automatic storage (i.e. not an ivar or static var, but just a local var) and that is \*not\* captured in a closure expression can be safely initialized in a non-threadsafe way, because the variable can not be accessed from more than one thread concurrently anyways.

Cons:  
- This would be the first concurrency primitive built into the language (at least as far as I know)  
- It may suggest to users of the language that other primitives (like var's) would be threadsafe too, which is obviously not the case.  
- There is at least \*some\* runtime overhead involved. It's not zero-cost. On the other hand, lazy initialization should only be used when the cost of initialization is much higher than the cost of creating and maintaining a thunk. And in that case, I think the performance characteristics are pretty well.  
- It may be out of scope for Swift 3 :-(

Proposed solution:

&nbsp;&nbsp;&nbsp;&nbsp;public lazy var foo: Type = fn()

is semantically equivalent to

&nbsp;&nbsp;&nbsp;&nbsp;private var \_lazy\_storage\_foo: Type?  
&nbsp;&nbsp;&nbsp;&nbsp;private var \_lazy\_lock\_foo: Lock  
&nbsp;&nbsp;&nbsp;&nbsp;public var foo: Type {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var result: Type?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_lazy\_lock\_foo.withLock {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(\_lazy\_storage\_foo == nil) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_lazy\_storage\_foo = fn()  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \_lazy\_storage\_foo!  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}

except that the builtin solution is much more efficient, and that the two private extra vars are not exposed when you use the lazy keyword.

All in all, I think that threadsafe lazy vars would be a nice feature for the language. I welcome feedback and am interested in a discussion.

Regards,  
Michael

---

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [April 6, 2016, 11:34pm UTC](https://forums.swift.org/t/proposal-threadsafe-lazy-vars/2084/2 "2016-04-06T23:34:17Z")

</div>

These are good points. I think we need both nonatomic and atomic lazy variables. The syntax and scaffolding will likely fall out of Property Behaviors:

> <https://github.com/apple/swift-evolution/blob/main/proposals/0030-property-behavior-decls.md>

All that’s left would be optimizing the implementation, which would be premature to discuss.

-Andy

> **···**
>
> > On Apr 6, 2016, at 2:07 PM, Michael Peternell via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Hi all,
> > 
> > lazy vars are not threadsafe in Swift 2. I saw code that uses lazy initialization in an unsafe way that introduces race conditions so often that I would be rich by now if get a penny each time. Many people use patterns like { if(\_var == nil) { \_var = [self \_calculateVar]; } return \_var; } or they just dispatch\_once, but forget that they are in an instance method, and that it will all break if there is ever more than one instance of that class.
> > 
> > I propose to make lazy vars atomic. Optionally, the old lazy var behavior could be renamed to something like lazy\_nonatomic.
> > 
> > I want to list some pros and cons for making lazy vars threadsafe:
> > 
> > Pros:  
> > - This proposal will not change the behavior of programs which are free from data races. I could argue that the change is therefore backwards-compatible.  
> > - I would say that programs which require lazy vars to be nonatomic in order to function correctly, are really bad style; threadsafe lazy vars behave much more deterministic. Many programs which use lazy vars incorrectly could suddenly become safe if this proposal is implemented.  
> > - The overhead would be minimal. For example, suppose we have a lazy var of type `NSImage`. We could represent that variable as a simple pointer which is initialized to NULL. The access could look something like this (this is just an example, there may be even more efficient solutions): {  
> > &nbsp;&nbsp;&nbsp;// we need to make sure that reads on \_var are not cached:  
> > &nbsp;&nbsp;&nbsp;memory\_read\_barrier(&\_var);  
> > &nbsp;&nbsp;&nbsp;// ^^and I'm not 100% sure that we really need that memory barrier.  
> > &nbsp;&nbsp;&nbsp;// (at least it's not needed for static vars, as proven by the implementation of dispatch\_once())
> > 
> > &nbsp;&nbsp;&nbsp;if(\_var == nil) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@synchronized(&\_var) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// ^^we synchronize on &\_var, and not on \_var  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// this is semantically invalid in objc, but the objc-runtime supports it.  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// The point I want to make is that we don't need extra storage for the  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// synchronization, in many cases.  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(\_var != nil) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \_var;  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... some code that initializes \_var  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//@synchronized() already employs memory barriers, so no additional barriers are needed  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//maybe we should use a non-recursive lock though..  
> > &nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;return \_var;  
> > }  
> > - Currently, if you need threadsafety, you cannot use lazy. You can of course wrap a lock around a nonatomic lazy var, but that would be much more inefficient than a native implementation.  
> > - I guess, no one will really complain if lazy var's are suddenly threadsafe. I also cannot see how it would break any code (except for contrived examples.)  
> > - In some cases, the nonatomic behavior can be used as an optimization, if it is semantically equivalent. For example, a lazy var that lives in automatic storage (i.e. not an ivar or static var, but just a local var) and that is \*not\* captured in a closure expression can be safely initialized in a non-threadsafe way, because the variable can not be accessed from more than one thread concurrently anyways.
> > 
> > Cons:  
> > - This would be the first concurrency primitive built into the language (at least as far as I know)  
> > - It may suggest to users of the language that other primitives (like var's) would be threadsafe too, which is obviously not the case.  
> > - There is at least \*some\* runtime overhead involved. It's not zero-cost. On the other hand, lazy initialization should only be used when the cost of initialization is much higher than the cost of creating and maintaining a thunk. And in that case, I think the performance characteristics are pretty well.  
> > - It may be out of scope for Swift 3 :-(
> > 
> > Proposed solution:
> > 
> > &nbsp;&nbsp;&nbsp;public lazy var foo: Type = fn()
> > 
> > is semantically equivalent to
> > 
> > &nbsp;&nbsp;&nbsp;private var \_lazy\_storage\_foo: Type?  
> > &nbsp;&nbsp;&nbsp;private var \_lazy\_lock\_foo: Lock  
> > &nbsp;&nbsp;&nbsp;public var foo: Type {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var result: Type?  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_lazy\_lock\_foo.withLock {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(\_lazy\_storage\_foo == nil) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_lazy\_storage\_foo = fn()  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \_lazy\_storage\_foo!  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;}
> > 
> > except that the builtin solution is much more efficient, and that the two private extra vars are not exposed when you use the lazy keyword.
> > 
> > All in all, I think that threadsafe lazy vars would be a nice feature for the language. I welcome feedback and am interested in a discussion.
