[swift-evolution] Proposal - Allow properties in Extensions

Matthew Johnson matthew at anandabits.com
Thu Dec 24 13:48:47 CST 2015

Sent from my iPad

> On Dec 24, 2015, at 1:31 PM, John McCall <rjmccall at apple.com> wrote:
>> On Dec 23, 2015, at 10:51 AM, Matthew Johnson <matthew at anandabits.com> wrote:
>>>> On Dec 23, 2015, at 12:50 PM, John McCall via swift-evolution <swift-evolution at swift.org> wrote:
>>>> On Dec 23, 2015, at 7:05 AM, Paul Cantrell <cantrell at pobox.com> wrote:
>>>>> On Dec 22, 2015, at 10:45 PM, John McCall via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> when you stuff a lot of functionality into a single class in most OO languages, there’s no real way to enforce its division into subsystems, because every method has direct access to every property and every other method.  In contrast, in Swift you can divide that class into distinct components with their own interface, state, and invariants, essentially making each component as good as its own type as far as encapsulation goes.
>>>> Can you elaborate on this, John? Extensions and protocols in Swift today still don’t solve the problem that shared _private_ class state has to be centralized. Or were you speaking as if this “properties in extensions” proposal were already implemented?
>>> Yes, that’s right.  I’m explaining why I think it makes sense to limit stored instance properties in extensions to class types: especially with some solution for private initialization of extensions, they enable intra-class encapsulation in a way that matters for classes and not really for other types.
>> How would private initialization of extensions work?
> Just spit-balling, but something like:
>  class A {
>    init(numbers: [Int]) {
>       // Definitive initialization requires initialization of all the extensions
>       // in the module that declare partial inits before the call to super.init.
>       self.init(counts: numbers)
>       // Okay, now we super.init.
>       super.init()
>       // Fully initialized now.
>     }
>  }
>  extension A {
>    let counts: [Int]
>    partial init(counts: [Int]) {
>      // Definitive initialization requires a partial init to initialize all the stored properties
>      // in this extension.  This all happens prior to the complete initialization of self,
>      // so unlike a normal init, there is no point in this initializer when unrestricted
>      // use of self is allowed.  If that’s required, it can be done with an ordinary method
>      // call.
>      //
>      // To start, partial initializers would not be allowed to use properties from other
>      // extensions or the main class.  We can consider ways to lift that restriction later.
>      self.counts = counts
>    }
>  }

I'm really not sure I like this very much.  It seems to be exactly what I was concerned about.  The primary advantage this seems to provide is encapsulation for the extension.  Unfortunately it also means the extension has a ripple effect requiring initializers elsewhere in the project to be updated.  This doesn't feel like an "extension" as it actually seems to be pretty invasive.  It gives me an uneasy feeling at first glance.

I would like to see some concrete examples of problems this solves and compelling reasons why it is better than the alternatives. 


More information about the swift-evolution mailing list