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

plx plxswift at icloud.com
Fri Dec 4 15:19:31 CST 2015


# 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 curious at this point to hear if there’s anything already on the roadmap and/or other community thoughts.

## Postscript

I'm aware that some of this can be done today via protocol extensions, but at least at present that technique has some serious drawbacks; I point it out only b/c it's possible Swift will wind up with enough improvements to protocol extensions to make a dedicated wrapper-synthesis, language-level feature unnecessary.

Additionally, although the sketch above *could* be implemented today via an external code-generation tool, the looming presence of a "standard" package manager makes it seem better to have this construct baked into the official tooling if possible.


More information about the swift-evolution mailing list