<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 7:13 PM, FĂ©lix Cloutier <<a href="mailto:felixcca@yahoo.ca" class="">felixcca@yahoo.ca</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=""><div class="">I started by reading the examples and I was very confused. This suggests to me that if you've never seen a var behavior before, you are going to wonder what the hell is going on. :-)</div></div></div></blockquote><div><br class=""></div><div>This is good feedback, thanks!</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="">Notable points of confusion:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">it's confusing to me that `self` is the containing type and the behavior name is the "behavior's self".</li></ul></div></div></div></blockquote><div><br class=""></div><div>Others have noted this too. Would it be less confusing if one had to explicitly name the "container" as a member, e.g.:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>var behavior synchronized {</div><div> container var parent: Synchronizable</div><div> base var value: Value</div><div><br class=""></div><div> get {</div><div> return parent.withLock { value }</div><div> }</div><div> set {</div><div> parent.withLock { value = newValue }</div><div> }</div><div>}</div></div></blockquote><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=""><ul class="MailOutline"><li class="">The `initializer` special field feels absolutely magic. Has anything else been considered, like an init param that has either a Value or an autoclosure returning one? (If we don't want to capture self, aren't we in for problems capturing self from accessors anyway?)</li></ul></div></div></div></blockquote><div><br class=""></div><div>An `init` parameter covers use cases where the initializer expression is used only during initialization, but doesn't let you use the initializer after initialization, which is necessary for `lazy`, `resettable`, and other use cases. Even with @autoclosure, it seems to me that, without `initializer`, we'd need to allocate per-property storage for the initializer expression to use it later, which is something I'd like to avoid.</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=""><ul class="MailOutline"><li class="">I see (after reading it) that `var behavior foo<Value>: Value` means that foo "applies to"/"wraps" Value, but I find it confusing to use a syntax more typically associated with "extends" or "implements" or "is a".</li></ul></div></div></div></blockquote><div><br class=""></div><div>Would it be less confusing if the type of the property were implicit? In discussion with Brent, I suggested a model where you say:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>var behavior foo { ... }</div></div></blockquote><div><div><br class=""></div><div>and if you want to constrain the types of properties that can instantiate the behavior, you use a where clause:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div>var behavior foo where Value: NSCopying { ... }</div><div><br class=""></div></div></blockquote>which optimizes the common case (no constraint), and might be easier to read.<br class=""><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="">Questions:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">Can a behavior have generic parameters that can't be inferred? Could I write, say, [fooable<Int>]?</li></ul></div></div></div></blockquote><div><br class=""></div><div>No, the generic parameters are only used to generalize the property type.</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=""><ul class="MailOutline"><li class="">What is the tradeoff between `eager` and `deferred`? Is it "only" that `deferred` side effects happen at the mercy of the behavior?</li><ul class=""><li class="">If so, isn't it a problem that behaviors aren't intrinsically explicit about whether they defer initialization? I can see that causing very subtle bugs.</li></ul></ul></div></div></div></blockquote><div><br class=""></div><div>The tradeoff is that an 'eager' initialization can be used in `init`, but that means that an initializer expression can't refer to `self`, because `self` is not fully initialized. This is how initializer expressions always work today:</div><div><br class=""></div><div>struct X {</div><div> var x = 0, y = 1</div><div> var z = x + y // Error</div><div>}</div><div><br class=""></div><div>A deferred initialization can only be evaluated *after* init, but because of that, it can refer to `self`, which people would like to be able to do with `lazy` (but currently can't):</div><div><br class=""></div><div>struct X {</div><div> var x = 0, y = 1</div><div> lazy var z = x + y // Theoretically OK</div><div>}</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=""><br class=""></div></div><div class="">Concerns:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">It looks like if you had a [resettable, observable] property, calling resettable.reset() would change the value from under `observable`'s feet.</li></ul></div></div></div></blockquote><div><br class=""></div><div>True. An unfortunate consequence of these things being user-defined is that there will always be "wrong" orderings of them. I'm not sure how much we can do about that.</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=""><br class=""></div><div class="">Comments:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">While it might be true that square brackets work better with other declarations that could eventually have behaviors, "var behavior" doesn't really lend itself to that kind of extensibility. Are we steering towards "func behavior", "class behavior", etc? Is it a problem if we are?</li></ul></div></div></div></div></blockquote><div><br class=""></div><div>Possibly. Note that square brackets are necessary even only for `var`, because you can declare a destructuring binding `var (x, y) = tuple`.</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=""><ul class="MailOutline"><li class="">I'd like to point out that the memoization example is a let variable with a behavior, which is explicitly forbidden by the current proposal.</li></ul></div></div></div></div></blockquote><div><br class=""></div><div>Thanks, missed that.</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=""><br class=""></div></div><div class="">Finally, I would like to throw the idea of "foo..resettable" to access foo's resettable behavior (or foo..reset() doing optionally-qualified lookup on foo's behavior methods).</div></div></div></blockquote><br class=""></div><div>Not a bad suggestion.</div><div><br class=""></div><div>Thanks again for the feedback!</div><div><br class=""></div><div>-Joe</div><br class=""></body></html>