> On Feb 10, 2017, at 12:23, Matthew Johnson <[email protected]> wrote:
> 
> 
>> On Feb 10, 2017, at 12:52 PM, Jordan Rose <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Hi, Matthew. Thank you for bringing up these issues. I'm going to break my 
>> feedback up into separate messages, because I think really the enum and 
>> protocol cases are unrelated. Open classes refer to classes that can be 
>> subclassed from clients of the current module, and similarly open protocols 
>> would be protocols that can be adopted from clients of the current module. 
>> Public-but-not-open classes cannot be subclassed from outside the current 
>> module, but they can still be subclassed within the module. By contrast, 
>> "open" enums can grow new cases in new versions of the library, but clients 
>> still can't add cases. (That's not a totally unreasonable feature to ever 
>> consider, but it's not the one we need now.)
> 
> Hi Jordan.  Thanks for replying to my post!
> 
> I understand the current behavior of `open` and how it would work for 
> protocols.  I also understand the vocabulary that has been used in talking 
> about “open” enums thus far.  What I am trying to point out is that there are 
> inconsistencies in the vocabulary we’ve been using thus far.  
> 
> The ideas of “open” and “closed” both talk about who is able to add to the 
> set of cases / subclasses / conforming types.  `public` (without annotation) 
> also does this.  But we haven’t been using the terms consistently - we use a 
> different meaning depending on which kind of entity we’re talking about.
> 
> For example, as you pointed out, `open` currently means both a module *and* 
> its clients can add new subclasses.  It doesn’t seem right to use this same 
> terminology to mean the module can add cases to an enum but clients *can’t* 
> add new cases to the enum.  I understand that “open” enums in the sense of 
> the current meaning of the `open` keyword are not a feature we need right 
> away.  I noted that this is specifically not proposed in my pitch.  But if we 
> ever *do* add this feature, `open enum` seems like the right way to spell it 
> (probably just using the existing case syntax in an extension to add cases in 
> the client).
> 
> It’s also worth pointing out that `public` currently has three distinct 
> meanings:
> * `public` enums *cannot* have a new case added in a future version of the 
> library is without a breaking change
> * `public` classes *can* have a new subclass added in a future version of the 
> library without a breaking change, but clients cannot add subclasses
> * `public` protocols have the same semantics as `open` classes, allowing 
> clients to add conforming types

* public structs *can* have new fields added
* public functions *can* add new parameters, as long as they have defaults, if 
you are careful about it
* public types *can* have new subtypes added
* public types *can* have new conformances added, although today that will 
break people and we need to do something about that (on another thread)

I think this is just a false equivalence. Adding cases to an enum within a 
module is fundamentally different from adding subclasses to a class outside the 
module. We should not be trying to jam enums into the same keyword that classes 
use just because I happened to use that term when writing the Library Evolution 
doc, even if it is a reasonable term for the thing.

(Matthew was very quick about replying to my first message and I was very slow 
with the second, and I think I already made this point better there. But for 
cross-referencing purposes it made sense to mention it here too.)


>> P.S. For classes, note that 'final' is essentially a performance 
>> optimization at this point. I'm not even sure we should bother displaying it 
>> in generated interfaces (although the compiler should still be able to take 
>> advantage of it in clients).
> 
> `final` can be pretty useful when reasoning about code.  It’s more than just 
> a performance optimization.  It also represents a compiler proof about our 
> code.

Ah, sorry, yes: 'final' is totally useful within a module to have the property 
enforced. It's just not super interesting outside the module. (It doesn't even 
mean there are no subclasses in all cases; features like KVO use a dynamic 
subclass in their implementation.)

Jordan
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to