[swift-evolution] [Draft] Mixins

Andrey Tarantsov andrey at tarantsov.com
Tue Mar 1 22:15:57 CST 2016


+1 (but *see below*)

Example:

> My custom Swift notification system currently has two problems that
> would be solved by mixins:
>
> 1. Anyone conforming to StdEmitterType has to provide “public var
>    _listeners = EventStorage()", which is obvious non-ideal (I have an
>    Xcode snippet for that).
>
> 2. I have EmitterType protocol that defines the publish/subscribe
>    contract, and StdEmitterType protocol that provides a standard
>    implementation of the publish/subscribe methods using a stored
>    _listeners property (provided by the conforming class/struct as
>    described in #1). The distinction between EmitterType and
>    StdEmitterType is confusing when both are called protocols, because
>    StdEmitterType is really a mixin. Calling EmitterType a protocol
>    and StdEmitterType a mixin would clear up the confusion.*
*

Because of reason #2, I'm strongly in support of using a separate
keyword.


*I do feel*, however, that maybe this isn't a single problem, but
instead *two orthogonal problems* that could have separate solutions:

1) *Go-style embedding*, where a struct's members become the members of
   its containing struct/class

2) an *“implicit delegate”* facility that allows a struct (you may call
   it a “mixin”) to access the self of its container, and to impose
   requirements on the container (funcs/vars that the container has to
   implement)

#1 is useful without #2 — the logging example doesn't need anything from
#it container, it just wants to add a variable

#2 is useful without #1 — I have other mixin-like examples that benefit
#from being included (a) in multiple copies, and/or (b) non-anonymously
#(with a meaningful name), and/or (c) privately.


*Examples of #2 without #1:*

— I have an activity system in my app that tracks the progress and
completion of a tree of long-running operations (think a Make-like build
process, or an IDE-style code analysis consisting of multiple steps
operating on multiple files). The relevant state management and
notification logic is encapsulated as ProcessorImpl mixin-like class
that tightly binds to its host via an initialization method:

public func initializeWithHost<Host: EmitterType>(host: Host, performs
performMethod: (Host) -> (Request, OperationContext) -> Promise<Void>)

...some classes perform multiple kinds of processing, so they end up
creating multiple ProcessorImpl's; and even for those classes that use
only one instance, it is helpful to give it a name (private let
analysisState = ProcessorImpl()) and to keep it private (it is manually
published via a separate property that has a protocol type)

— my current Delayed class that implements something similar to
performSelector:afterDelay: / cancelPerformSelector in Objective-C, or
to function throttling/unbouncing in JavaScript. It has to be a class,
because it contains mutable state that is modified from within
dispatch_async. Would be great for it to instead be a mixin that would
use the “self” of its container, without creating a separate object.


Thoughts?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160302/a2a54c63/attachment.html>


More information about the swift-evolution mailing list