[swift-evolution] Proposal: Automatic Wrapper Synthesis / "deriving"

John McCall rjmccall at apple.com
Fri Dec 4 16:26:49 CST 2015


> On Dec 4, 2015, at 1:19 PM, plx <plxswift at icloud.com> wrote:
> # A `wrapper` / `deriving` Construct
> 
> I'm sure a construct along these lines has been requested numerous times and is hopefully already on the roadmap.
> 
> 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.
> 
> ## Design Sketch
> 
> It ought to be possible to write something like this:
> 
>    // an example:
>    struct SectionIndex
>      wrapping Int
>      as index
>      satisfying precondition { $0 >= 0 }
>      deriving Equatable, Comparable, Hashable {
>      // declaration can continue in here
>    }
> 
> ...which, when compiled, would be "expanded" along these lines:
> 
>    struct SectionIndex {
> 
>      // would have been `wrappedValue` w/out the `as index` clause
>      let index: Int
> 
>      init(_ index: Int) {
>        precondition(index >= 0) 
>        // ^ would have been assert(index >= 0) 
>        //   had we used `satisfying { $0 >= 0 }`,
>        //   and omitted entirely had we omitted a `satisfying` clause
>        self.index = index
>      }
> 
>    }
> 
>    extension SectionIndex : Equatable {
>    }
> 
>    // synthesized unless explicitly written-out
>    func ==(lhs: SectionIndex, rhs: SectionIndex) -> Bool {
>      return lhs.index == rhs.index
>    }
> 
>    // same for Comparable, Hashable, all done in the obvious way    
> 
>    // there’s a lot of utility in synthesizing something like this,
>    //  I can expand on it if necessary:
>    extension SectionIndex: ValueWrapperType {
>      typealias WrappedType = Int
>    }
> 
> ...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 think this enough to sketch the way the feature would look and how it would work. 

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 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.

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?).

John.


More information about the swift-evolution mailing list