<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 16, 2016, at 4:39 AM, Tino Heth &lt;<a href="mailto:2th@gmx.de" class="">2th@gmx.de</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I'm always in favor of removing special cases (like lazy and willSet/didSet), so the idea of property behaviors itself is very appealing to me.<div class="">There's one downside, though:</div><div class="">The proposal makes some keywords obsolete, but introduces a whole bunch of new stuff in exchange — and all of this only can be used with properties…</div><div class=""><br class=""></div><div class="">I hope you agree with me that there is merit in keeping the language small (it's called "Swift", not "Turkey" ;-), and that the proposal would improve if it's possible to slim it down.</div><div class=""><br class=""></div><div class="">Imho the first step to add property behaviors should be refining how properties are modeled in Swift:</div><div class="">In many languages, properties are represented as a pair of methods (setter and getter), and their absence has several downsides (functional programming works best with functions ;-).</div><div class=""><br class=""></div><div class="">As soon as there is a way to read and write properties in a functional way, their behaviors could be expressed in a universal manner:</div><div class="">Afaics, all major use cases for behaviors can be implemented as simple "decorators" — in fact, I could simulate most examples from the proposal in a tiny playground (a part of it is attached).</div><div class="">Of course, the simulation is ugly, but I am confident that some nice ideas would come up if properties were more accessible.</div></div></div></blockquote><div><br class=""></div><div>Believe me, I would prefer to keep the language impact small too. There are a couple of issues that make this difficult with property behaviors:</div><div><br class=""></div><div>- First of all, Swift properties are *not* a simple getter-setter pair. Get and set is an inefficient protocol for value types, since any mutation of part of a value through get/set requires copying the entire value by 'get', mutating the temporary copy, then copying the entire modified value back by 'set'. If properties were limited to a get/set interface, every partial update of an array 'foo.arrayProperty[0] = 1' would force at minimum one full copy of the array buffer. It's better to think of a property as a mutable projection function, `inout T -&gt; inout U`, and in fact I plan to propose allowing 'inout' returns as a way of abstracting over properties and other projections.</div><div><br class=""></div><div>- If we had inout-projecting functions, it's true that the property implementation part of most behaviors could be modeled as functional transformations, e.g.:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>// Turn an optional property into a 'lazy' non-optional property</div></div><div><div>func lazy&lt;Container, Value&gt;(@autoclosure initialValue initialValue: () -&gt; Value, property: inout Value?) -&gt; inout Value {</div></div><div><div>&nbsp; func adapter() -&gt; inout Value</div></div><div><div>&nbsp; &nbsp; get {</div></div><div><div>&nbsp; &nbsp; &nbsp; if let value = property() { return value }</div></div><div><div>&nbsp; &nbsp; &nbsp; let initial = initialValue()</div></div><div><div>&nbsp; &nbsp; &nbsp; property() = initial</div></div><div><div>&nbsp; &nbsp; &nbsp; return initial</div></div><div><div>&nbsp; &nbsp; }</div></div><div><div>&nbsp; &nbsp; set {</div></div><div><div>&nbsp; &nbsp; &nbsp; property() = newValue</div></div><div><div>&nbsp; &nbsp; }</div></div><div><div>&nbsp; }</div></div><div><div>&nbsp; return adapter</div></div><div><div>}</div></div></blockquote><div><div><br class=""></div><div>However, there's more to a behavior than the property implementation itself. We also want behaviors to be able to encapsulate the backing storage for their properties, including their initialization. The compiler could perhaps infer backward from the signature of `lazy` above that, in order to produce a lazy property of type `Value`, it needs to back it with a property of type `Value?`, but it still doesn't know how or when `lazy` expects that storage to be initialized. Furthermore, we want behaviors to be able to attach behavior-specific operations to their properties, such as to clear a lazy property or reset a property to a private default value. While both of these issues can be addressed by explicitly exposing the backing storage as a separate property:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>var fooStorage: Int? = nil</div><div>var foo: Int { return &amp;lazy(initialValue: 1738, property: &amp;fooStorage) }</div><div><br class=""></div></div></blockquote>that's quite a bit of boilerplate, and it also clutters the user interface for the type, since the storage now appears as a separate entity from the property itself. We want behaviors to be lightweight and easy to use, and on balance I think the best way to deliver that is with some specialized functionality.<div class=""><br class=""></div><div class=""><div class="">-Joe</div></div></body></html>