[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