<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 11, 2016, at 6:08 AM, Wallacy &lt;<a href="mailto:wallacyf@gmail.com" class="">wallacyf@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class="">To be honest, I did not expect was to find some kind of consensus with respect to structs. The technical challenge appears to be greater than the benefit.</div><div class=""><br class=""></div><div class="">And about class, I imagine that today would only be possible to implement using objc protocols, right? Using the associated objects mechanism.</div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Keeping limited to objc protocols is a feature that might be worth?<br class=""></div></div></div></blockquote><div><br class=""></div>IMO, If we don’t do it portably for all classes and class-bound protocols, it’s not worth it. We don’t really want to introduce new @objc-only features.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">"</div><div class=""><span style="font-size:13px;line-height:19.5px" class="">&nbsp;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)</span><br class=""></div><div class="">"</div><div class=""><br class=""></div><div class="">The problem with that is will make the protocol to much limited or not? Maybe not worth the trouble.<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Possibly not worth the trouble. If nothing else, it’s very hard to explain the limitations without deep-diving into the implementation details, which is an indicator that it’s “too complicated."</div><div class=""><br class=""></div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">Em seg, 11 de jan de 2016 às 02:34, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>&gt; escreveu:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2016, at 6:43 PM, Wallacy via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class=""><div class=""><div dir="ltr" class="">TL;DR<div class=""><br class=""></div><div class="">Thinking about some problems presented here this mailing list. I believe that by following the same concepts behind the default protocol implementations, allowing the same mechanism to provide default properties can be a remarkable gain for language.</div><div class=""><br class=""></div><div class="">Rationale:</div><div class=""><br class=""></div><div class=""><div class="">It has been proposed here also on this list, a need to produce abstract classes, one of the reasons that need, is because is not possible to declare properties in the same way as we declare default implementation on protocols.</div><div class="">I also believe that this can help in the concept of multiple inheritance, and serve as an aid to the default implementation on protocols, and "complete" the&nbsp;Protocol-Oriented Programming concept.</div><div class=""><br class=""></div><div class="">For example:</div><div class=""><br class=""></div><div class=""><div class="">protocol Named {</div><div class="">&nbsp; &nbsp; var name: String { get }</div><div class="">}</div><div class="">protocol Aged {</div><div class="">&nbsp; &nbsp; var age: Int { get }</div><div class="">}</div><div class="">struct Person: Named, Aged {</div><div class="">&nbsp; &nbsp; var name: String</div><div class="">&nbsp; &nbsp; var age: Int</div><div class="">}</div><div class=""><br class=""></div><div class="">extension Aged where Self: Named { &nbsp; &nbsp;</div><div class="">&nbsp; &nbsp; func wishHappyBirthday() { // regular default implementation</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; print("Happy birthday \(<a href="http://self.name/" target="_blank" class="">self.name</a>) - you're \(self.age)!")</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; var birthdayVideo: AVPlayerItem? // nil is a default value</div><div class="">}</div></div><div class=""><div class="">...</div><div class="">func playBirthdayMediaFrom(person: Person){</div><div class="">&nbsp; &nbsp; var avPlayer = AVPlayer(playerItem: person.birthdayVideo)</div><div class="">&nbsp; &nbsp; // etc...</div><div class="">}</div></div><div class=""><br class=""></div><div class="">One of thousands of using this feature is to prevent us to create variables that are not actually part of the data model we are shaping.<br class=""></div><div class=""><br class=""></div><div class=""><div class="">birthdayVideo in this case would be any variable that is not part of our model, but need to be associated with the object (or structure) in some context of our application. (And not be used anywhere else in the APP or another API).</div><div class=""><br class=""></div><div class="">Other examples maybe a counter helper, weak reference to something, etc. There is a infinite examples when we need to declare some variable just to make the "api" happy like add a observer, holding some value, and use this again to removeobserver in dealloc.</div></div><div class=""><br class=""></div><div class="">I believe that the same rules and the same mechanisms involving default implementation functions, should govern this default property implementation, and any discussion about it on the problems on protocols rules should be made separate this thread.</div></div></div></div></blockquote><br class=""></div></div><div style="word-wrap:break-word" class=""><div class="">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.</div><div class=""><br class=""></div><div class="">In the existing language, one can only introduce stored properties in the primary definition of the type. That’s because, when we create an instance of that type, we need to know how much storage to allocate for that instance. So, right now, we don’t even allow, e.g.,</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>struct MyStruct { }</div><div class=""><span style="white-space:pre-wrap" class="">        </span>extension MyStruct { var storage: Int = 0 } // error: extensions may not contain stored properties</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>class MyClass { }</div><div class=""><span style="white-space:pre-wrap" class="">        </span>extension MyClass { var storage: Int = 0 } // error: extensions may not contain stored properties</div><div class=""><br class=""></div><div class="">because, in the worst case, we don’t know about the storage required for the “storage” property until after we’ve allocated some instances of MyStruct or MyClass, and we can’t simply go back and resize those instances when we learn about the “storage” property. The “worst case” here could come about with shared libraries: put the MyStruct/MyClass primary definitions into an app, then put the extensions into a separate shared library. The app creates some MyStruct and MyClass instances, then loads the shared library, and now we have a problem: those instances have no storage for “storage.”</div><div class=""><br class=""></div><div class="">We could relax the requirement to allow extensions in the same module as the primary definition of that type to introduce stored properties, because they’re compiled along with the primary type definition anyway. This doesn’t solve out-of-module extensions, of course.</div><div class=""><br class=""></div><div class="">We could embed a pointer into each instance that points off to the stored properties for that instance. The pointer would refer to some lazily-allocated memory on the heap with that extra storage. However, this would either bloat every data structure by a pointer (including “Int”!) or have to be opt-in, neither of which are great. I don’t think there is any reasonable implementation for out-of-module stored properties in extensions of value types (struct/enum).</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>* Only allow them on class-bound protocols, where there is a reasonable implementation model</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>* 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).</div><div class=""><br class=""></div><div class="">Either handles the example brought up in the discussion of abstract base classes.</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>- Doug</div><div class=""><br class=""></div><br class=""></div></blockquote></div></div>
</div></blockquote></div><br class=""></body></html>