[swift-evolution] Properties on Default Protocol Implementations

Wallacy wallacyf at gmail.com
Mon Jan 11 08:08:13 CST 2016


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.

And about class, I imagine that today would only be possible to implement
using objc protocols, right? Using the associated objects mechanism.

Keeping limited to objc protocols is a feature that might be worth?

"
 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)
"

The problem with that is will make the protocol to much limited or not?
Maybe not worth the trouble.


Em seg, 11 de jan de 2016 às 02:34, Douglas Gregor <dgregor at apple.com>
escreveu:

>
> On Jan 10, 2016, at 6:43 PM, Wallacy via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> TL;DR
>
> 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.
>
> Rationale:
>
> 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.
> 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 Protocol-Oriented Programming concept.
>
> For example:
>
> protocol Named {
>     var name: String { get }
> }
> protocol Aged {
>     var age: Int { get }
> }
> struct Person: Named, Aged {
>     var name: String
>     var age: Int
> }
>
> extension Aged where Self: Named {
>     func wishHappyBirthday() { // regular default implementation
>         print("Happy birthday \(self.name) - you're \(self.age)!")
>     }
>     var birthdayVideo: AVPlayerItem? // nil is a default value
> }
> ...
> func playBirthdayMediaFrom(person: Person){
>     var avPlayer = AVPlayer(playerItem: person.birthdayVideo)
>     // etc...
> }
>
> 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.
>
> 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).
>
> 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.
>
> 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.
>
>
> 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.
>
> 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.,
>
> struct MyStruct { }
> extension MyStruct { var storage: Int = 0 } // error: extensions may not
> contain stored properties
>
> class MyClass { }
> extension MyClass { var storage: Int = 0 } // error: extensions may not
> contain stored properties
>
> 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.”
>
> 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.
>
> 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).
>
> 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.
>
> 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:
>
> * Only allow them on class-bound protocols, where there is a reasonable
> implementation model
>
> * 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).
>
> Either handles the example brought up in the discussion of abstract base
> classes.
>
> - Doug
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/a55a3a6a/attachment.html>


More information about the swift-evolution mailing list