<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 18, 2016, at 4:29 PM, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" class="">jtbandes@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><span style="font-size:12.8px" class="">Here are some of my thoughts from reading through the current version (</span><a href="https://gist.github.com/jckarter/50b838e7f036fe85eaa3" target="_blank" style="font-size:12.8px" class="">https://gist.github.com/jckarter/50b838e7f036fe85eaa3</a><span style="font-size:12.8px" class="">)</span><span style="font-size:12.8px" class="">. Apologies if this duplicates what anyone else has said; the thread is kind of unmanageable :)</span><div style="font-size:12.8px" class=""><div class=""><br class=""></div><div class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">&nbsp; // Behaviors can declare that properties using the behavior require<br class="">&nbsp; // a `deferred initializer` expression. When deferred, the<br class="">&nbsp; // initializer expression is assumed to be evaluated after<br class="">&nbsp; // initialization of the containing value, which allows it to refer<br class="">&nbsp; // to `self`. If declared, `initializer` is bound in accessors and<br class="">&nbsp; // methods of the behavior.<br class="">&nbsp; deferred initializer: Value</blockquote><div class=""><br class=""></div><div class="">This seems like an important feature, but the syntax is strange to me. It looks like it would be declaring storage inside the behavior, but it's really specifying the type of something used in the containing object's property declaration.</div></div><div class=""><br class=""></div><div class="">I can think of a couple alternatives:</div><div class=""><br class=""></div><div class="">1. Rather than passing an initial value in the containing object like "var [lazy] prop = someInitialValue", pass it explicitly as a parameter to the behavior,</div><div class="">&nbsp; &nbsp; like "var [ lazy({ return someInitialValue }) ] prop: Type"</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; I think it might be generally useful for behaviors' initializers to take arguments; it'd handle more than just this case. For example, you could have a behavior called synchronized(maxConcurrentRequests: Int) which would allow arguments passed to affect the behavior's...behavior.</div></div></div></div></div></blockquote><div><br class=""></div><div>You can parameterize using accessors, which can also theoretically replace all uses of a bound initializer. For example:</div><div><br class=""></div><div>var [lazy] prop: Type { initialValue { return someInitialValue } }</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class="">2. Make the "deferred"-ness a modifier/attribute on the behavior declaration, like "public @deferred var behavior lazy&lt;Value&gt;: Value { ... }", which would make the implicit initialValue inaccessible from the behavior's init(). The same with @eager.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">x.lazy.clear() // Invokes `lazy`'s `clear` method</blockquote><div class=""><br class=""></div><div class="">As I think others have mentioned, this is ambiguous if x itself has a property called "lazy". I'd be reasonably satisfied with any of the proposed solutions to this.</div><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">&nbsp; base var value: Int</blockquote><div class=""><br class=""></div><div class="">I don't think I like the fact that this needs to be explicitly declared. Do all behaviors have to use the same identifier for them to be composable? Could you use "super" to mean this, instead of explicitly declaring a base property?</div></div></div></div></div></div></blockquote><div><br class=""></div><div>The identifier 'value' is up to the declaration to decide. Some behaviors don't have a base; anything that needs to control the storage, such as 'lazy', can't really be composed this way. I thought about using 'super' for this, but a behavior would still need a way to declare whether it has a 'super' or not. It's also weird to bind both 'self' and 'super' with totally different meanings. A number of people have objected to the special treatment of 'self' I've proposed already.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><br class=""></div><div class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Accessor requirements can be made optional by specifying a default implementation:<br class="">&nbsp; mutating accessor willSet(newValue: Value) {<br class="">&nbsp; &nbsp; // do nothing by default<br class="">&nbsp; }</blockquote><div class=""><br class=""></div><div class="">Up until this point, I was thinking of accessor declarations like protocol requirements, in that they have no implementation ("accessor foo()" like "func foo()"). I think the lack of implementation is what makes it clear that these are requirements, not things the behavior is implementing.</div></div></div></div></div></div></blockquote><div><br class=""></div><div>It's planned for the future to allow protocol declarations to contain default implementations in-line, and I see 'optional' protocol requirements as being only for ObjC compatibility and not something you should use in pure Swift designs.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><div class=""><br class=""></div><div class="">So perhaps you could use the "optional" specifier to indicate that they aren't required, rather than allowing an implementation block in the behavior. "optional accessor foo()" would allow the behavior's implementation to use "foo?()".</div></div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">var [foo] x: Int {&nbsp;</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">&nbsp; &nbsp; bar(myArg) { print(myArg) } // `arg` explicitly bound to `myArg`&nbsp;</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">}</blockquote><div class=""><br class=""></div><div class="">Why not require a type annotation for parameters here? I recognize this matches the current syntax of set(newValue), but it would be more flexible if this were more like a function declaration.</div></div></div></div></div></blockquote><div><br class=""></div><div>We could optionally accept type annotations, but the argument types should almost always be inferrable.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">To preserve the shorthand for get-only computed properties, if the accessor declaration consists of code like a function body, that code is used as the implementation of a single accessor named "get".</blockquote><div class=""><br class=""></div><div class="">This seems a bit vestigial. Maybe it could be allowed only when a computed property is declared without using any behaviors.</div></div></div></div></div></blockquote><div><br class=""></div>That would be reasonable.<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><br class=""></div><div class="">A few more questions:</div><div class=""><br class=""></div><div class="">- Can a behavior's own properties/storage use other behaviors? Can a behavior be recursive?</div></div></div></div></div></blockquote><div><br class=""></div><div>Yes, and yes, as long as in doing so you don't produce infinite storage.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><br class=""></div><div class="">- What of deinitializers for behaviors? Would it be possible, for example, to make an observable behavior whose willSet/didSet run during init and deinit (which Swift's current property observers can't do)?</div></div></div></div></div></blockquote><div><br class=""></div><div>I don't think we want to change how behaviors work in init and deinit. It isn't possible to invoke methods before `self` is initialized, and it's dangerous to do so during `deinit`.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class=""><br class=""></div><div class="">- Are accessor implementations allowed to access the "current" property value? Currently, inside "var foo { didSet { … } }" you can access the current value by referencing "foo".</div></div></div></div></div></blockquote><div><br class=""></div><div>Accessor implementations can access the behavior's storage, so they can either access their stored property containing the property value directly, or factor more complex accessor logic out into a helper method.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div style="font-size:12.8px" class=""><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Overall this looks great. I'm looking forward to it. :-)</div></div></div></div></div></blockquote></div><br class=""><div class="">Thanks!</div><div class=""><br class=""></div><div class="">-Joe</div></body></html>