<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=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""></pre>I feel like, if we implement automatic derivation for structs that wrap one value, we can just as easily implement automatic derivation for all product types for which the children conform to the protocols in question, and there’s a provided implementation for derivation by combining values.<div class=""><br class=""></div><div class="">Consider Hashable. A very common implementation of <font face="Menlo" class="">hashValue</font>&nbsp;is <font face="Menlo" class="">xor</font>-ing all the members’ hash values together.</div><div class="">We could actually implement this right now given Swift’s reflection system (if we were able to conditionally cast to <font face="Menlo" class="">Hashable</font> or any protocol with a <font face="Menlo" class="">Self</font>&nbsp;requirement).</div><div class=""><br class=""></div><div class="">Consider this:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">struct HashableDerivable deriving Hashable {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; let string: String // because String is already Hashable</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; let integer: Int &nbsp; // and Int is Hashable</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; // then HashableDerivable is trivially Hashable.</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">/// This implementation is absolutely derivable at compile time.</font></div><div class=""><font face="Menlo" class="">extension HashableDerivable: Hashable {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var hashValue: Int {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return string.hashValue ^ integer.hashValue</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class="">func ==(lhs: HashableDerivable, rhs: HashableDerivable) -&gt; Bool {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; return lhs.string == rhs.string &amp;&amp; lhs.integer == rhs.integer</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">// one can also use Reflection to derive this at runtime</font></div></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">extension Mirror {</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; func canDeriveHashable() -&gt; Bool {</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; if self.subjectType is Hashable&nbsp;{ return true } // this is currently a compiler error</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; for child in self.children {</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let mirror = Mirror(reflecting: child)</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if !mirror.canDeriveHashable() { return false }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return true</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; func deriveHashValue() -&gt; Int {</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; if !self.canDeriveHashable() { fatalError("Boy, I wish this didn't have to happen at runtime.") }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; guard let firstChild = self.children.first as? Hashable /* also an error */ else { fatalError("no children") }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return self.children.dropFirst().reduce(firstChild.hashValue) { (hash, _: (_: String?, value: Any)) -&gt; T in</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return hash ^ (value as! Hashable).hashValue</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class="">}</font></div></div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; line-height: normal;" class="">Of course, this is something that can be done at compile time, which would make protocol conformance really, really simple.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">We already do this, using the <font face="Menlo" class="">Mirror</font> API, for <font face="Menlo" class="">CustomStringConvertible</font>.</div><div class=""><div class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">&gt;<i class=""> On Dec 4, 2015, at 4:26 PM, John McCall &lt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">rjmccall at apple.com</a>&gt; wrote:
</i>&gt;<i class=""> 
</i>&gt;&gt;<i class=""> On Dec 4, 2015, at 1:19 PM, plx &lt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">plxswift at icloud.com</a>&gt; wrote:
</i>&gt;&gt;<i class=""> # A `wrapper` / `deriving` Construct
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> I'm sure a construct along these lines has been requested numerous times and is hopefully already on the roadmap.
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> The point of this email is to put out a reasonably-*concrete* sketch as a way of soliciting community feedback on the specifics of how such a construct might look-and-work within Swift; hopefully I’ve gone far-enough to be interesting, but not too much further than that.
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> ## Design Sketch
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> It ought to be possible to write something like this:
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   // an example:
</i>&gt;&gt;<i class="">   struct SectionIndex
</i>&gt;&gt;<i class="">     wrapping Int
</i>&gt;&gt;<i class="">     as index
</i>&gt;&gt;<i class="">     satisfying precondition { $0 &gt;= 0 }
</i>&gt;&gt;<i class="">     deriving Equatable, Comparable, Hashable {
</i>&gt;&gt;<i class="">     // declaration can continue in here
</i>&gt;&gt;<i class="">   }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> ...which, when compiled, would be "expanded" along these lines:
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   struct SectionIndex {
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     // would have been `wrappedValue` w/out the `as index` clause
</i>&gt;&gt;<i class="">     let index: Int
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     init(_ index: Int) {
</i>&gt;&gt;<i class="">       precondition(index &gt;= 0) 
</i>&gt;&gt;<i class="">       // ^ would have been assert(index &gt;= 0) 
</i>&gt;&gt;<i class="">       //   had we used `satisfying { $0 &gt;= 0 }`,
</i>&gt;&gt;<i class="">       //   and omitted entirely had we omitted a `satisfying` clause
</i>&gt;&gt;<i class="">       self.index = index
</i>&gt;&gt;<i class="">     }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   extension SectionIndex : Equatable {
</i>&gt;&gt;<i class="">   }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   // synthesized unless explicitly written-out
</i>&gt;&gt;<i class="">   func ==(lhs: SectionIndex, rhs: SectionIndex) -&gt; Bool {
</i>&gt;&gt;<i class="">     return lhs.index == rhs.index
</i>&gt;&gt;<i class="">   }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   // same for Comparable, Hashable, all done in the obvious way    
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">   // there’s a lot of utility in synthesizing something like this,
</i>&gt;&gt;<i class="">   //  I can expand on it if necessary:
</i>&gt;&gt;<i class="">   extension SectionIndex: ValueWrapperType {
</i>&gt;&gt;<i class="">     typealias WrappedType = Int
</i>&gt;&gt;<i class="">   }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> ...where each method/init/subscript/etc in the derived protocols gets synthesized at compile-time, if not explicitly implemented; similarly, if not explicitly-declared, the derived protocols' typealiases can be synthesized in obvious ways, and it seems acceptable to simply fail to compile (and inform the user of the need to make an explicit-declaration) in cases where such synthesis is impossible.
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> I think this enough to sketch the way the feature would look and how it would work. 
</i>&gt;<i class=""> 
</i>&gt;<i class=""> I’m not sure what work is being done by “wrapping X as Y” here; it seems like just another way of expressing a stored property.
</i>&gt;<i class=""> 
</i>&gt;<i class=""> I think we’re all interested in a “deriving” proposal.  However, the key problem that a serious proposal would have to address is not picking the syntax, but describing how derivation would actually work.  We’d prefer not to just hard-code rules in the compiler for specific protocols.
</i>&gt;<i class=""> 
</i>&gt;<i class=""> For example, derivation presumably involves recursively invoking the given operation on each of the stored properties (what does “on” mean? which parameters are changed, and which are passed through?) and then merging the results (how?).
</i>&gt;<i class=""> 
</i>&gt;<i class=""> John.
</i>
Apologies for leaving too much out.

I meant to propose that the `deriving` in this place would enforce the wrapper type only wrapped a single stored value, warranting the distinct syntax; I seem to have edited-out both an explicit statement that this assumed a single-stored-property and to have omitted a comment in the `//declaration can continue in here` that no additional stored-properties could be declared (analogous to the rules current applied within extensions).

Yes, constraining a `deriving` construct to only support wrappers containing a single stored property would, on the one hand, be somewhat limiting, but on the other hand it would seemingly allow trivial solutions to the issues you bring up:

- `on` is unambiguous as there’s only one thing it can be “on"
- there’s no ordering-of-operations to have to worry about
- there’s no merging-of-results to have to worry about
- i’m guessing there’s no parameters needing to getting changed (but I’m not 100% on what you mean here)
- there’s no associated-type incoherency to worry about (unless user error introduces it)

…there’s least one tricky case (if you want the wrapper to replace one of the wrapped type’s typealiases with a wrapper).

…and at least for me, there’s enough value in that simplified wrapper-synthesis / deriving-type construct to take the time to check community interest. 

Thanks for taking the time to read and send feedback.

PS:

On the other hand, if this becomes writable:

    protocol WrapperType {
       typealias WrappedValue
       var wrappedValue: { get }
    }

    extension WrapperType : Equatable where WrappedValue: Equatable {
    }

    func ==&lt;W:WrapperType where W.WrappedValue:Equatable&gt;(lhs: W, rhs: W) -&gt; Bool {
      return lhs.wrappedValue == rhs.wrappedValue
    }

…etc., then it’s possible (albeit moderately unpleasant) to just write suitable glue logic out longhand on an as-needed basis (and with the caveat that all types wrapping T would potentially adopt all of T’s protocols even when potentially undesirable).</pre></blockquote><div class=""><br class=""></div></div></div></body></html>