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"? 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