<div dir="ltr">FWIW:<div><br></div><div><div>I quick look of my code base (in ObjC), i found 39 code points with I use ObjC associated objects, one of them is a crazy database manager (for postgres) with automatic look for the database, search the tables, search for the program to find classes with the same name, and automatic add a observer for all rows properties that match (surprisingly works).</div><div><br></div><div>Others codes are more simpler, but my point with this proposal, despite all technical issues, is avoid some &quot;to much creative&quot; solutions to model the code, one in particular I am looking now (in swift), has 8 core data properties, and 8 transient and irrelevante properties just to maintain the everything sane (like avplayer Periodic Time Observer), and all 8 has default implementation using extensions, will be good declare some of the storage properties in a protocol and make each &quot;behavior&quot; (like monitoring the avplayer) a protocol to be reused.</div><div><br></div><div>And think about the PwS noted by Chris, yes, maybe can be confusing add another &quot;kind&quot; of protocols, but like the Self requirement, generally, if well implemented, its just a matter of time (not so much) to people understand and drive a good protocol-oriented-programing code.</div></div></div><br><div class="gmail_quote"><div dir="ltr">Em seg, 11 de jan de 2016 às 16:35, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>&gt; escreveu:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
&gt; On Jan 11, 2016, at 10:27 AM, Chris Lattner &lt;<a href="mailto:clattner@apple.com" target="_blank">clattner@apple.com</a>&gt; wrote:<br>
&gt;<br>
&gt; On Jan 10, 2016, at 8:34 PM, Douglas Gregor via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt; Default implementations of functions don’t require per-instance state, while adding a stored property via a protocol extension does. Let’s step back to a simpler problem: stored properties in (non-protocol) extensions.<br>
&gt;&gt;<br>
&gt;&gt; For classes, where we have object identity, we could have a side table containing the stored properties (keyed on the object’s address). This is how Objective-C’s associated objects work, and it’s a reasonable module for out-of-module stored properties in extensions of classes.<br>
&gt;&gt;<br>
&gt;&gt; Getting back to stored properties in protocol extensions, the general feature isn’t implementable without having some mechanism for out-of-module stored properties in extensions of structs and enums, so you can limit it in a few ways:<br>
&gt;&gt;<br>
&gt;&gt;      * Only allow them on class-bound protocols, where there is a reasonable implementation model<br>
&gt;&gt;<br>
&gt;&gt;      * Allow them as default implementations within a protocol (not an extension of a protocol!); a type can conform to that protocol either by providing its own implementation of that property or somewhere where it is reasonable for the default implementation to inject a stored property into that context (e.g., on the primary type, within the same module as the primary type, or on a class).<br>
&gt;&gt;<br>
&gt;&gt; Either handles the example brought up in the discussion of abstract base classes.<br>
&gt;<br>
&gt; Hi Doug,<br>
&gt;<br>
&gt; Have you considered this similar-but-different approach?<br>
<br>
Not this particular shade, but I understand your motivation.<br>
<br>
&gt;<br>
&gt; - Allow extensions on classes (only) within the same module/resilience domain as the class to add stored properties. This would keep them inline in the instance.<br>
&gt; - Allow protocols to have stored property declarations, introducing a new “protocol with storage” (PwS) concept.<br>
&gt; - Classes can directly conform to a PwS in its definition, or within an extension inside the same module/resilience domain.<br>
&gt;<br>
&gt; Just this would give many of the benefits of a full mix-in programming model.  People could define these protocols, and their local implementation of the type can benefit from them.  It doesn’t support retroactive mixin’ing, but that is probably a good thing.  I’m assuming that we don’t want to allow adding state to structs within a resilience domain, just because I don’t think that is actually a good thing to add to the programming model (other reasonable people will surely disagree).<br>
&gt;<br>
&gt; This base model could then be extended:<br>
&gt; - Structs could conform to a PwS in their definition, but not an extension.  We could optionally require the struct to redeclare the properties to improve readability of the struct, but it wouldn’t be required from an implementation perspective.<br>
&gt; - Classes could conform to a PwS across resilience boundaries, but wouldn’t get the state: they’d have to implement the storage requirement with a computed property.<br>
&gt; - We could introduce an “associated objects” property behavior that makes providing the computed property very straight-forward, using the out of band implementation approach of ObjC.<br>
&gt;<br>
&gt; The advantages of this approach I see are:<br>
&gt;<br>
&gt; 1) implementable, always a bonus.<br>
<br>
This isn’t a different from my proposal in that regard ;)<br>
<br>
&gt; 2) keeps predictable performance.  You don’t get out “associated objects” overhead unexpectedly.  All state is always stored inline.<br>
&gt; 3) retroactive mixins are possible, but explicit.<br>
<br>
… this is the real benefit, and I agree. The overhead of associated objects should require one to explicitly opt-in.<br>
<br>
&gt; The primary downside of this approach is that it introduces yet another weird protocol variant with limitations and behaviors, making the model more complicated.<br>
<br>
<br>
I think these semantics are reasonable, and the limitation is the same as what I proposed: it’s hard to describe why the limitations are what they are without a deep-dive into the implementation model.<br>
<br>
        - Doug<br>
<br>
</blockquote></div>