[swift-evolution] Proposal: label-only constructors

Drew Crawford drew at sealedabstract.com
Sun Dec 13 06:49:36 CST 2015


Oftentimes I want to have multiple parameterless constructors. In the immediate case, I want a Key for various different cryptographic algorithms:

    let a = Key(forRSA: true) //2048-bits
    let b = Key(forCurve25519: true) //256-bits
    let c = Key(forAES: true) //128-bits

There is no "parameter" to pass here; in particular the user should not be expected to know off the top of their head what the key size for Curve25519 is.

With the current limits of the language, I am generally forced to vend a parameter and associated label (I typically use type Bool) and pass a "dontcare" value in, e.g. `true` in the above.

I propose to eliminate this, so I can write

    Key {
        init(forRSA) { /* */ }
    }
    let a = Key(forRSA)

This eliminates the parameter, and the associated mystery about what happens if you pass `false` to one of these constructors.

FAQ:

Q: Can't you have one constructor that takes an enum parameter?
A: Enum parameters cannot have cases with distinct access modifiers, as constructors often are.  Also, combining unrelated code into one constructor makes me sad.

Q: Can't you create subclasses RSAKey, Curve25519Key etc. with distinct constructors?
A: Well first of all, Key is probably a `struct`, so no, you can't create subclasses of it.  Also, the only thing differentiating them is the constructor, not e.g. other overridden methods or variables, so subclassing feels an unnecessarily heavy abstraction.

Q: Can we extend this to support arbitrary labels e.g. `init(random length: 2000)` vs `init(zeroed length: 2000)`, `mkdir(path, creatingIntermediateDirectoriesIfRequired)` and many more?
A: Yes, although these are probably more controversial proposals than simply supporting multiple parameterless constructors.


More information about the swift-evolution mailing list