<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Ok, fair enough. Then here a few ideas how to fix it and still stay in-line with Anton’s proposal (that i still consider much more attractive):<div class=""><br class=""></div><div class="">1. Allow behaviours to specify abstract members that need to be implemented (akin to protocols) and get the initial value of lazy from there, e.g.:</div><div class=""><br class=""></div><div class=""> var lazy x : T {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func load() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>return 33</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""> }</div><div class=""><br class=""></div><div class=""> Pros: clean and clear. Cons: verbosity.</div><div class=""><br class=""></div><div class="">2. Allow behaviours to have members stored per property declaration and not per property instance. These members are tied to the type-level storage of the host item (e.g. class and not instance). A closure that initialises the lazy storage can be stored at that level, thus solving the storage overhead issue. One can use the static declarations for this (although a new storage class might be appropriate). Note that Python uses this kind of approach per default: instances of property descriptors are created per class that hosts a property and not per instance. The property getter/setter then receives the specific object instance to manipulate the value specific to that instance. </div><div class=""><br class=""></div><div class=""> Pros: clean and clear. Cons: potentially need new storage declaration.</div><div class=""><br class=""></div><div class="">— Taras </div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 12 Feb 2016, at 22:59, Joe Groff <<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 12, 2016, at 1:45 PM, Taras Zakharko <<a href="mailto:taras.zakharko@uzh.ch" class="">taras.zakharko@uzh.ch</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I like Anton’s proposal much better! Clean, obvious and down to the point. <div class=""><br class=""><div class=""><blockquote type="cite" class="">On 12 Feb 2016, at 21:44, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</blockquote></div><div class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">IMO it's unacceptable to have to store a closure for every individual lazy property. That significantly increases the storage cost of the abstraction.</div><div class=""><br class=""></div><div class="">-Joe</div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div></div></div><div class="">Maybe I am missing something obvious here but what would be a practical example of a lazy variable that does not rely on a closure to provide the initial value? Besides, storing an additional pointer per property is what, 8 bytes overhead? Barely worth mentioning. And of course, if you want to be very efficient about it you can always use a global hash map to store the closures. </div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">A Swift closure is two pointers wide—a function pointer, and a context pointer. The per-instance overhead for Optional<T> will already cost a word for many types without an extra bit or representation for 'None'.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class="">BTW, the lazy implementation you propose also has additional overhead, but its hidden (initialValue needs to be stored somewhere before the first call to get). In fact, your solution might be even worse in terms of storage overhead, because it implies that individual closure with unique environment needs to be created for getters of every instance of the property with different initialiser. </div></div></div></div></div></blockquote><br class=""></div><div class="">As currently implemented, 'lazy' inlines the initializer expression into the property's getter implementation, so the only overhead is some code size in the getter function. A behavior implementation of [lazy] needs to afford the same opportunity to the optimizer. One way we could model this is as 'static' members in the behavior, perhaps.</div><div class=""><br class=""></div><div class="">-Joe</div></div></div></blockquote></div><br class=""></div></body></html>