> On 15 Feb 2017, at 02:16, Xiaodi Wu via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> So, perhaps I'm being simplistic here, but--
> 
> At the end of the day, aren't we simply trying to enable a resiliency 
> feature? Could it not be said that an enum where future added cases aren't 
> source-breaking is a more resilient enum?
> 
> Since there is consensus that the status quo is desirable for a lot of use 
> cases, couldn't we keep spelling it "public enum" and just spell this 
> proposed more resilient enum "@resilient public enum”?

If it’s got to be done, this is the best solution, but to my mind, it shouldn’t 
be done at all. 

There is no way that a library designer can possibly determine what constitutes 
“resilient” behaviour on the part of the client software. Maybe adding a 
default clause is the right thing, but maybe the default clause does something 
that it shouldn’t for some new enumeration cases. As the client software 
designer, my only defence is an exhaustive switch statement that relies on the 
compiler to tell me the it is no longer exhaustive. Yes, it means software in 
the field will crash until I distribute a new version but that is often 
preferable to other silent consequences. I really do not want to be forced to 
add a default to a switch that might reduce the safety of my software.

Adding new cases to any enumeration where the client software is meant to take 
different actions based on the different cases is source breaking. End of 
story. No point in trying to mark them as resilient.

Adding cases to enumerations that are meant to be passed in to the library e.g. 
an enumeration that specifies a compositing operation or a string encoding may 
well not be source breaking (how can you tell in every case?) but it’s unlikely 
that the client is going to be testing those enumerations in a switch statement 
anyway.



> On Tue, Feb 14, 2017 at 10:09 Matthew Johnson via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> > On Feb 14, 2017, at 3:43 AM, Brent Royal-Gordon <br...@architechies.com> 
> > wrote:
> >
> >> On Feb 13, 2017, at 7:45 AM, Matthew Johnson <matt...@anandabits.com> 
> >> wrote:
> >>
> >> If you look closely, when most people say “closed enum” they mean a fixed, 
> >> complete set of cases that are all public.  But when people say “closed 
> >> protocol” they don’t actually mean a fixed, complete set of conformances 
> >> that are all public.  They simply mean clients cannot add conformances.  
> >> This is the semantic contract of resilient enums, not closed enums.
> >
> > Yes, our traditional terminology here has been a little bit confused.
> >
> >>> What I instead suggest is that we think of a closed enum as being like a 
> >>> fragile (non-resilient) struct. In both cases, you are committing to a 
> >>> particular design for the type. So I think we should give them both the 
> >>> same keyword—something like:
> >>>
> >>>     @fixed struct Person {
> >>>             var name: String
> >>>             var birthDate: Date
> >>>     }
> >>>     @fixed enum Edge {
> >>>             case start
> >>>             case end
> >>>     }
> >>>
> >>
> >> You omitted public here.  Does that mean you intend for `@fixed` to imply 
> >> public visibility?  If so, I could get behind this.  But I am curious why 
> >> you made it an attribute rather than a keyword.
> >
> > No, I'm sorry, I meant to say `@fixed public struct` and `@fixed public 
> > enum`. I don't think `@fixed` implies public-ness, either, so it would need 
> > to be paired with a `public` keyword. There *may* be keywords we could use 
> > that would, like `exposed`
> 
> I agree that `fixed` (and `closed`) don’t imply `public` in terms of the 
> colloquial meaning of the words and there is a reasonable case that `open` 
> does.  I’m not sure I like `exposed`, but maybe it’s possible to find a 
> keyword that would more directly imply `public`.
> 
> > , but I'm not sure we want to make this feature so prominent,
> 
> I have some trouble getting on board with requiring an annotation *in 
> addition* to `public` for the reasons I have already stated, and which led to 
> `open` becoming an access modifier rather than an annotation.  It’s possible 
> I could be convinced otherwise, but I think it would require data showing 
> that this really is a rare edge case.  If the relatively frequency of closed 
> vs resilient enums is reasonably similar to the relative frequency of public 
> vs open enums I think there is a strong case to make them carry the same 
> syntactic weight, as we did with `open`.
> 
> > and I'm not sure how that would work with classes you want to both expose 
> > and permit subclassing of. (Would that be `exposed open class Foo`?)
> 
> 
> Can you elaborate on what you mean by "classes you want to both expose and 
> permit subclassing of”?  Do you mean commit to the set of fields being fixed 
> like you indicated with a struct?  If so, I’m not sure that is a valuable 
> combination and my instinct is to ban it.
> 
> If we did want to support something like that it points to keeping `closed` 
> (as in cases, subclasses and conformances) orthogonal to `fixed` (as in the 
> set of stored properties).
> 
> >
> >>> I don't see it mentioned here (maybe I just missed it), but even though 
> >>> we *could* do exhaustiveness checking on non-open protocols, I'm not 
> >>> convinced that's a good idea. Usually when you have several types 
> >>> conforming to a protocol, you should access type-specific behavior 
> >>> through polymorphism, not by switching on the protocol. A protocol is 
> >>> supposed to represent a behavior, not just mark a type in some arbitrary 
> >>> way.
> >>
> >> I agree that you should usually be adding polymorphism, but preventing 
> >> exhaustive switch on what is effectively a style argument seems like an 
> >> unnecessary restriction to me.  There will be times when it could be used 
> >> to good effect.  I think the community has done a pretty good job of 
> >> figuring out how to use Swift’s many features well and don’t believe it 
> >> would be frequently abused.
> >
> > I agree we shouldn't change the language to *prevent* bad style. But this 
> > would go beyond that—we'd be putting specific engineering effort solely 
> > into *enabling* bad style. At minimum, this should fall so far down our 
> > to-do list that we'll probably never get to it.
> 
> This assumes that switching over conforming types is bad style.  One of the 
> biggest problems with switching over subclasses or conforming types is the 
> fact that you don’t get compiler verification of exhaustiveness.  If the 
> language supports exhaustive switching for closed classes and protocols this 
> becomes a non-issue.
> 
> I don’t know of any languages that support a kind of type which supports 
> generic and dynamic dispatch as well as exhaustive switch.  It may be 
> interesting to have the ability to organize some methods by type (i.e. 
> protocol requirements) and other methods by function (i.e. a protocol 
> extension method with an exhaustive switch).
> 
> When you have exhaustive switch these are really just two different ways to 
> organize code.  Neither one is inherently better.  Each has strengths 
> different strengths.  Why not allow the language to support both and let 
> programmers decide which organization of their code is best in a particular 
> case?
> 
> >
> >>> I still support this general approach. One spelling could simply be 
> >>> `@nonopen`. Although if we don't use `closed`, we could simply use 
> >>> `@closed` like I suggested—here it really *would* be an antonym to `open`.
> >>
> >> I like the idea of using `@nonopen` for the transitional attribute.  Both 
> >> because it “removes the openness” that `public protocol` currently 
> >> implies.  In that sense it is probably the most accurate term we could 
> >> find and it’s also pretty concise.
> >
> > It also sounds a little bit awkward, which is normally a reason not to use 
> > it, but perhaps that's actually a good thing in a temporary, transitional 
> > keyword.
> >
> >>>> A similar mult-release strategy would work for migrating public enums.
> >>>
> >>> What is it that needs migrating here? Lack of exhaustiveness checking? It 
> >>> sounds like we were planning to break that anyway in some fashion.
> >>
> >> Public enums are not currently resilient.  Clients are allowed to switch 
> >> over them without a `default` clause.  This means that client code will 
> >> fail to compile in a version of Swift where `public enum` has the 
> >> resilient contract unless the library changes to adopt closed semantics or 
> >> the client adds a default case.
> >
> > My thinking was that, since most existing `public` enums should probably 
> > not be `@fixed`, we should just change the behavior and let some switch 
> > statements break.  Most `public` protocols, on the other hand, ought to 
> > become `open`, so we should flag that change and require an explicit marker 
> > like `@nonopen` if you really don't want to change over. But I could be 
> > convinced otherwise.
> 
> I think this hits on the basis of our disagreement.  Is it really the case 
> that *most* existing `public` enums should probably not be `@fixed`?  Have 
> you done an analysis to support this?  Not just of the standard library, but 
> also Apple’s frameworks and open source modules on Github?  We might learn 
> something interesting by doing an analysis like this.  It certainly wouldn’t 
> hurt.
> 
> If it turns out that closed / fixed is *often* (say 30-40% of the cases or 
> more) the desirable contract using an annotation would result in noisy 
> boilerplate.
> 
> On the other hand, if it turns out to be relatively rare (say 5-10%) it would 
> become easier to forget the annotation, making an error of omission.  Of 
> course that error can be corrected pretty easily so maybe we it wouldn’t be a 
> big deal if it really is rare.
> 
> >
> > --
> > Brent Royal-Gordon
> > Architechies
> >
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to