<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Thu, Dec 17, 2015, at 04:36 PM, Joe Groff wrote:<br></div>
<blockquote type="cite"><div><div><blockquote type="cite"><div><blockquote><div>Resettable properties<br></div>
</blockquote><div>&nbsp;</div>
<div>The implementation here is a bit weird. If the property is nil, it invokes the initializer expression, every single time it's accessed. And the underlying value is optional. This is really implemented basically like a lazy property that doesn't automatically initialize itself.<br></div>
<div>&nbsp;</div>
<div>Instead I'd expect a resettable property to have eager-initialization, and to just eagerly re-initialize the property whenever it's reset. This way the underlying storage isn't Optional, the initializer expression is invoked at more predictable times, and it only invokes the initializer once per reset.<br></div>
<div>&nbsp;</div>
<div>The problem with this change is the initializer expression needs to be provided to the behavior when reset() is invoked rather than when the getter/setter is called.<br></div>
</div>
</blockquote><div>&nbsp;</div>
<div>Yeah, the implementation here is admittedly contorted around the fact reset() can't receive the initializer expression directly, and we don't want to store it anywhere in the property.<br></div>
</div>
</div>
</blockquote><div>&nbsp;</div>
<div>We definitely can't have behaviors storing closures. Any closure that references `self` would then become a retain cycle. And of course for value types the closure would have captured an outdated copy of self. I think we should state upfront that any closure type given to a behavior should be required to be @noescape.<br></div>
<div>&nbsp;</div>
<div>Something I meant to suggest but forgot was the idea that maybe a Behavior at runtime should be a struct that's initialized every time it needs to do something, and takes init arguments for the initializer and any relevant accessors (e.g. willSet, didSet). This is similar to how you already have it optionally take that stuff, but if the struct is initialized fresh on each access, with the initializer and accessors being provided as @noescape bound closures (implemented by hidden function declarations), then even things like reset() will have access to all the info it needs to do whatever it wants. Although I'm not quite sure offhand how to model reset() being able to mutate the property if the behavior doesn't keep the property storage inline (which, as I previously mentioned, has composability problems). Maybe each method would actually take an inout parameter as the first argument that it can use to read from/write to the underlying property?<br></div>
<div>&nbsp;</div>
<div>Alternatively, properties could not even have a runtime struct representation but just be collections of static functions. Each function would take an inout parameter for the underlying property, and then optional parameters for the various things the user can specify (initializer and accessors). This would make more sense when using the explicit `behavior` keyword because you'd just model this as functions nested inside the behavior scope, with no type declaration anywhere.<br></div>
<div>&nbsp;</div>
<blockquote type="cite"><div><div><blockquote type="cite"><div><div>&nbsp;</div>
<blockquote><div>The backing property has internal visibility by default<br></div>
</blockquote><div>&nbsp;</div>
<div>In most cases I'd recommend private by default. Just because I have an internal property doesn't mean the underlying implementation detail should be internal. In 100% of the cases where I've written a computed property backed by a second stored property (typically named with a _ prefix), the stored property is always private, because nobody has any business looking at it except for the class/struct it belongs to.<br></div>
<div>&nbsp;</div>
<div>Although actually, having said that, there's at least one behavior (resettable) that only makes sense if it's just as visible as the property itself (e.g. so it should be public on a public property).<br></div>
<div>&nbsp;</div>
<div>And come to think of it, just because the class designer didn't anticipate a desire to access the underlying storage of a lazy property (e.g. to check if it's been initialized yet) doesn't mean the user of the property doesn't have a reason to get at that.<br></div>
<div>&nbsp;</div>
<div>So I'm actually now leaning to making it default to the same accessibility as the property itself (e.g. public, if the property is public). Any behaviors that have internal implementation details that should never be exposed (e.g. memoized should never expose its box, but maybe it should expose an accessor to check if it's initialized) can mark those properties/methods as internal or private and that accessibility modifier would be obeyed. Which is to say, the behavior itself should always be accessible on a property, but implementation details of the behavior are subject to the normal accessibility rules there.<br></div>
</div>
</blockquote><div>&nbsp;</div>
<div>I don't think we can default to anything more than internal. Public behaviors become an API liability you can never resiliently change, and we generally design to ensure that API publication is a conscious design decision.<br></div>
</div>
</div>
</blockquote><div>&nbsp;</div>
<div>I'm inclined to say that some behaviors (like resettable and synchronized) are conceptually part of the public API (assuming the property is public), and some behaviors (like lazy and property observers) aren't.<br></div>
<div>&nbsp;</div>
<div>With the `behavior` keyword we could let each behavior decide for itself what its default accessibility level should be. That is a bit unusual, but otherwise everyone who uses `resettable` on a public property will actually have to say `public resettable` for it to make sense, and similarly `synchronized` should typically be visible to consumers of the API (even though there's no actual API on the behavior itself to use) because the threading behavior of an API is part of its public contract. Of course you could always say `private synchronized` if you wanted to override this.<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard</div>
</body>
</html>