[swift-evolution] ValueEnumerable protocol with derived implementation for enums

John McCall rjmccall at apple.com
Sat Apr 23 01:34:59 CDT 2016

> On Apr 22, 2016, at 11:11 PM, Jacob Bandes-Storch <jtbandes at gmail.com> wrote:
> On Fri, Apr 22, 2016 at 10:50 PM, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
> I have not been following this discussion, but I would be extremely antsy about guaranteeing any particular representation for the set of values.  Guaranteeing a contiguous array implementation seems like a really bad idea, especially if that's taken to mean that we're going to actually provide a static global array.  But there's no way to avoid providing a public API, because a public conformance itself implies a public API with some level of corresponding overhead.
> A "compiler magic" version of the feature, like #allValues(MyEnum), could generate a static array *internal* to the caller's module, but I'm sure there are implications or details of this which I'm not aware of.

That cannot be reconciled with resilience.  The caller cannot reliably know the set of stored cases; only the defining module can.

For similar reasons, only the defining module can be allowed to magically derive a conformance to your protocol, if indeed it's done with a protocol.

> I don't remember the details of Java enums from my days as a Java programmer, but reading between the lines of your description, it sounds to me like Java originally made overly-strong guarantees that it decided to walk back in a later release.  That's a lesson we should heed.
> Maybe I missed something, but that's not how I interpreted it. The guarantee was/is simply that getEnumConstants() returns the values in source order. If the class being loaded changes (excuse my Java ignorance if that's the wrong terminology), you may end up with different results at runtime, but it's still an array of the values in the order they're defined in the class. Of course, Java enums seem to be much simpler (they can have payloads/members, but the values are fixed for the cases you define at compile-time).

I see.  Yes, they're just saying that getEnumConstants makes a stronger guarantee.

> I just noticed there's a MyEnum.values() method too, but it seems to do the same thing as getEnumConstants(). <http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html <http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html>>

Note that getEnumConstants() has to create a new array every time, since Java arrays are mutable and have reference semantics.

> The interaction of resilience with enums is in principle quite straightforward: you ought to be able to arbitrarily change the set of stored cases for a resilient enum.  That includes adding cases, changing existing cases to be "computed", and so on.  (We haven't yet designed what it ought to mean for a case to be computed, but I assume it at least means providing an injector (Payload -> Enum) and a projector (Enum -> Payload?); whether and how to allow computed cases to factor into exhaustiveness checking is a separate but crucial question.)  The fundamental problem for features like this is that adding a case with a payload is not compatible with actually being enumerable, outside of special cases and/or some formal-but-useless notion of recursive enumerability.  But even if you couldn't add new cases with payloads (which is something we might consider adding as an intermediate opt-in constraint), and thus the type was necessarily finite, I can't imagine wanting to promise to return a static global array.
> Non-"simple" enums (those with cases with payloads, generic enums, etc.) are out of scope for this proposal. There are multiple ways in which you might want them to be "enumerable", and anyway, it seems like a job for better reflection. There's some discussion in the "Future directions" section at the bottom (which I'll probably remove): <https://github.com/jtbandes/swift-evolution/blob/case-enumerable/proposals/0000-derived-collection-of-enum-cases.md <https://github.com/jtbandes/swift-evolution/blob/case-enumerable/proposals/0000-derived-collection-of-enum-cases.md>>  For now we'd like to start with something simple but functional.

I have no idea why you're ruling out generic enums if you're ruling out enums with payloads.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160422/72d41e4a/attachment.html>

More information about the swift-evolution mailing list