<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 13, 2016, at 9:34 PM, David Waite <<a href="mailto:david@alkaline-solutions.com" class="">david@alkaline-solutions.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="">Joe,<div class=""><br class=""></div><div class="">There seem to be many new syntactic features to support this, both inside and outside of a behavior. I was wondering if you had considered/had comments an alternative approach where you declare an ordinary new value type which meets certain rules and ‘wraps’ the existing type, then define new syntax/features in Swift for having the wrapper (or possibly even multiple levels of wrappers) be more transparent for use.</div><div class=""><br class=""></div><div class="">For instance, the existing ‘lazy’ keyword functionality might have been implemented by a type Lazy<T></div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">struct</span> Lazy<T> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">private</span> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> val:<span style="font-variant-ligatures: no-common-ligatures; color: #6122ae" class="">T</span>?</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">let</span> supplier:()-><span style="font-variant-ligatures: no-common-ligatures; color: #6122ae" class="">T</span></div></div><div style="font-size: 11px;" class=""><p style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""> <br class="webkit-block-placeholder"></p></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">init</span>(supplier:()-><span style="font-variant-ligatures: no-common-ligatures; color: #6122ae" class="">T</span>) {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">self</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">supplier</span> = supplier</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><br class=""></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> value:<span style="font-variant-ligatures: no-common-ligatures; color: #6122ae" class="">T</span> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">get</span> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">val</span> == <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">nil</span> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">val</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">supplier</span>()</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">val</span>!</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">set</span> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">val</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">value</span></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">func</span> clear() {</div><div style="margin: 0px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">val</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">nil</span></div><div style="margin: 0px; line-height: normal;" class=""> }</div><div class=""><br class=""></div></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class="">}</div></div></blockquote><div class=""><br class=""></div><div class="">With the following as an example of use (without any additional syntactic features)</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> globally = <span style="font-variant-ligatures: no-common-ligatures; color: #c91b13" class="">"Test"</span></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">class</span> Foo {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> bar = <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">Lazy</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>> {</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(201, 27, 19);" class=""><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">globally</span><span style="" class=""> = </span>"Side effect"</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #0435ff" class="">1</span></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class="">}</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><br class=""></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(83, 154, 164);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">print</span><span style="" class="">(</span>globally<span style="" class="">)</span></div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(83, 154, 164);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3c828c" class="">Foo</span><span style="" class="">().</span>bar<span style="" class="">.</span>value</div></div><div style="font-size: 11px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(83, 154, 164);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">print</span><span style="" class="">(</span>globally<span style="" class="">)</span></div><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(83, 154, 164);" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3c828c" class="">Foo</span>().bar.<span style="font-variant-ligatures: no-common-ligatures; color: #294c50" class="">clear</span>()</div></div></div></blockquote><div class=""><br class=""></div><div class="">One could opt into a syntax to allow value to be hidden from view. In fact, I can hide the use of the Lazy struct today if I’m willing to write more code:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">class</span> Foo {</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">private</span> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> internalbar = <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">Lazy</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>> {</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(201, 27, 19);" class=""> <span style="color: rgb(195, 34, 117);" class="">return</span> <span style="color: rgb(4, 53, 255);" class="">1</span></div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">var</span> bar:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span> {</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">get</span> {</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(83, 154, 164);" class=""><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">return</span><span style="" class=""> </span>internalbar<span style="" class="">.</span>value</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c32275" class="">set</span> {</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">internalbar</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">value</span> = newValue</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div style="font-size: 8px;" class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; font-size: 14px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">print</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #3c828c" class="">Foo</span>().<span style="font-variant-ligatures: no-common-ligatures; color: #539aa4" class="">bar</span>)</div></div></blockquote><div class=""><br class=""></div><div class="">Which actually has the benefit of being able to call the clear() method without new syntax, and being able to control access to clear separate from the getter/setter</div></div></div></blockquote><div><br class=""></div><div>Yes, this was explored by the previous iteration of the proposal. The exact design you propose is unacceptable for us, because it requires per-property instance storage for the "supplier" closure, which would be a massive regression from how `lazy` works today. To avoid this, the parameters of the property declaration need to be passed to the property implementation as well, so I had proposed using a subscript to handle it:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>struct Lazy<T> {</div></div><div><div> var value: T? = nil</div></div><div><div><br class=""></div></div><div><div> subscript(initialValue: () -> T) -> T { ... }</div></div><div><div>}</div></div></blockquote><div><div><br class=""></div><div>which is workable, but if we want this feature to have the flexibility to subsume all of our existing ad-hoc property features, the informal protocol between the behavior and the initialization and subscripting of the underlying type becomes fairly complex. Using types to encapsulate behaviors also introduces some runtime overhead we'd like to avoid if possible.</div><div><br class=""></div><div>-Joe</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=""><br class=""></div><div class="">-DW</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 13, 2016, at 3:07 PM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Thanks everyone for the first round of feedback on my behaviors proposal. I've revised it with the following changes:<br class=""><br class="">- Instead of relying on mapping behaviors to function or type member lookup, I've introduced a new purpose-built 'var behavior' declaration, which declares the accessor and initializer requirements and provides the storage and behavior methods of the property. I think this gives a clearer design for authoring behaviors, and allows for a more efficient and flexible implementation model.<br class="">- I've backed off from trying to include 'let' behaviors. As many of you noted, it's better to tackle immutable computed properties more holistically than to try to backdoor them in.<br class="">- I suggest changing the declaration syntax to use a behavior to square brackets—'var [behavior] foo'—which avoids ambiguity with destructuring 'var' bindings, and also works with future candidates for behavior decoration, particularly `subscript`.<br class=""><br class="">Here's the revised proposal:<br class=""><br class=""><a href="https://gist.github.com/jckarter/50b838e7f036fe85eaa3" class="">https://gist.github.com/jckarter/50b838e7f036fe85eaa3</a><br class=""><br class="">For reference, here's the previous iteration:<br class=""><br class=""><a href="https://gist.github.com/jckarter/f3d392cf183c6b2b2ac3" class="">https://gist.github.com/jckarter/f3d392cf183c6b2b2ac3</a><br class=""><br class="">Thanks for taking a look!<br class=""><br class="">-Joe<br class="">_______________________________________________<br class="">swift-evolution mailing list<br class="">swift-evolution@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></body></html>