[swift-evolution] [Pitch] consistent public access modifiers

Xiaodi Wu xiaodi.wu at gmail.com
Tue Feb 14 20:16:02 CST 2017


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 at swift.org> wrote:

>
> > On Feb 14, 2017, at 3:43 AM, Brent Royal-Gordon <brent at architechies.com>
> wrote:
> >
> >> On Feb 13, 2017, at 7:45 AM, Matthew Johnson <matthew at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170215/21e2b215/attachment.html>


More information about the swift-evolution mailing list