<div dir="ltr">On Wed, Jan 10, 2018 at 5:06 AM, Brent Royal-Gordon <span dir="ltr">&lt;<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><blockquote type="cite"><span class="gmail-"><div>On Jan 9, 2018, at 10:26 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail-m_2640090446032120583Apple-interchange-newline"></span><span class="gmail-"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I continue to have concerns about this proposal, and I&#39;m gravely and very bitterly disappointed that the concerns have not even been acknowledged in the Alternatives section, which is in my view the minimum action that an author should take when points are raised during a pitch phase, even (and especially) when the author disagrees, along with a cogent write-up of why the proposed design is superior in the author&#39;s view to the alternative. In this case, the proposal authors write:</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">  &quot;The community has not raised any solutions whose APIs differ significantly from this proposal, except for solutions which provide strictly more functionality.&quot;</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This is false, as I have offered a solution in the past whose API differs entirely from this proposal, and which provides strictly a subset of the functionality which goes to the core of the issue at stake.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></div></span></blockquote><div><br></div><div>I can&#39;t speak for the other co-authors, but for my part, this was an oversight and I apologize for it. I think we should have discussed your `MyType.self` alternative.</div><div><br></div><div>I won&#39;t rehash the entire discussion in previous threads, but to summarize my objections:</div></div></div></blockquote><div><br></div><div>Again, I do appreciate the detailed reply. Time is never enough, so I&#39;ll try to be both concise and complete in my reply. Hopefully, it&#39;ll live up to your example in terms of thoroughness.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div></div><div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>1. `MyType.self` is harder to understand for someone who&#39;s never seen it than `MyType.allValues`. For instance, the expression `AccountStatus.allValues[0]` is completely self-explanatory, while `AccountStatus.self[0]` is more obscure and would require a trip to the documentation. (And since `self` here is a language keyword, not a real member, the most obvious route to the documentation is not available.) In my opinion, we should not prefer the `MyType.self` syntax.</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>2. Even if the community disagrees with me and thinks `MyType.self` is a better syntax than `MyType.allValues`, it is not better *enough* to outweigh the costs:</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• The metatype solution provides no additional functionality; it is merely a matter of which syntax we choose to support, and how much effort this support requires.</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• Conforming the metatype to `Collection` requires a lot of type system features we do not currently have. Currently, structural types cannot conform to protocols, and metatypes are a structural type. Metatypes also cannot have subscripts currently. Your proposed design has a lot of prerequisites. That is not in and of itself disqualifying, but it should be weighed against it.</div></div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• You suggest that we should add bits and pieces of &quot;`Collection` functionality&quot; incrementally as engineering resources become available. The problem is that the most valuable part of the &quot;`Collection` functionality&quot; is conformance to `Collection` or at least `Sequence`, not the existence of any particular members of `Collection`, and this is the part that would require the most engineering resources.</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• A large part of the work we would do before supporting this conformance would be disposed of immediately once we could get it. For instance, all of the work to support having a metatype instead of a sequence in a `for-in` statement would be thrown away as soon as we could conform to `Sequence`. So this looks less like slowly building up pieces of the feature until we have all of them in place, and more like creating temporary hacks to emulate the feature until we have the time to do it right.</div><div><br></div><div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• While this feature is not a showstopper, it is a highly desirable convenience. The proposal documents the high demand for this feature, so I won&#39;t elaborate on this point further.</div></div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>• Therefore, adopting this design would add a lot of engineering complexity before we could fully support a highly desirable feature, merely to get a syntax that we *might* prefer.</div><div><br></div><div>To summarize the summary: The primary advantage of `MyType.self` is that it&#39;s elegant. To get that elegance, we must trade away getting a fully-functional implementation sooner, spending a lot of engineering resources (much of which would be wasted in the end), and—most crucially in my opinion—clarity at the point of use. It&#39;s not worth it.</div><span class="gmail-"><div><br></div></span></div></div></blockquote><div><br></div><div>Let me take two steps back, then address your points (1) and (2). One overarching critique of mine is that you are conflating two (related) features into one. The stated motivation is the desire to enumerate all the cases of an enum (let&#39;s call this problem A). The presented solution enlarges the problem to be solved to that of enumerating all the values of a type (let&#39;s call this problem B, which is kind of (*) a superset of problem A). </div><div><br></div><div>(*) More on the &quot;kind of&quot; part later.</div><div><br></div><div>It does not follow that simply because a solution to A is often requested, therefore a solution to B needs to be urgently implemented. This is a straight-up error in logic. If, instead, problem A were a superset of problem B and not the other way around, then the argument would follow logically. But that is not the case here. Let&#39;s return to this issue a little later. I bring it up here because points (1) and (2) are about solutions to problem B.</div><div><br></div><div>So, on to your points (1) and (2). To restate my original objection, it is that conceptually, &quot;all the possible values of a variable&quot; is a definition of a type. Whether it&#39;s &quot;elegant&quot; or not, &quot;obscure&quot; or not, if all the values representable by a type can be enumerated, then the metatype meets the semantics requirements of conformance to Collection. This is simply true (or it&#39;s not, and I&#39;m mistaken), but in any case it&#39;s not a matter of opinion or taste but of fact.</div><div><br></div><div>Now, if one day we try to solve problem B and you say, &quot;I think `MyType.self` is obscure, and I&#39;d like to have a synonym called `MyType.allValues` that&#39;s more discoverable,&quot; then the wisdom of adding a member named `allValues` could be evaluated on its own merits. But if `MyType.allValues != MyType.self` because of missing features in Swift, then quite simply Swift is incapable of fully supporting a solution to problem B.</div><div><br></div><div>But that&#39;s still OK: what you&#39;ve documented is that there is high demand for a solution to problem A, a kind of (*) subset of problem B. If problem B cannot be solved in an appropriate manner for Swift 5, it doesn&#39;t have to be solved at all for Swift 5. We should focus on problem A.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class="gmail-"><div></div><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Earlier in this thread (or was it in the companion one?), another community member suggested that if `allValues` were to conform to `Sequence` instead of `Collection`, then even types that have an infinite number of possible values could conform to `ValueEnumerable`. Here&#39;s the rub: the definition of a type, or at least one of them, _is_ precisely the set of all possible values of a variable. If unconstrained by finiteness, then *all types* would meet the semantic requirements of `ValueEnumerable`.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><br></div></span><div>Not quite. There are types whose valid values are unknowable; for instance, a type representing &quot;the ID of a record on the server&quot; cannot know which IDs actually exist on the server, merely which ones *could* exist, and so an implementation of `allValues` would return invalid instances.</div></div></div></blockquote><div><br></div><div>Careful. You&#39;re conflating different definitions of &quot;validity&quot; here. If I store the ID of an existing record in a variable of type T, then another process deletes that record, the ID I have stored is plainly still of type T. So then the question is, valid for *what*? (Certainly, for example, it&#39;s still valid as far as the type checker is concerned.)</div><div><br></div><div>Or to rephrase, what kind of &quot;possible&quot; are we talking about in terms of &quot;possible values&quot;? Are the only &quot;possible&quot; ID values those that exist in the database (i.e., &quot;actual&quot; ID values)? Or are they the full range of &quot;possible&quot; ID values present and future according to the table schema? This is not merely word play here: it demonstrates fuzziness in the semantic requirements of your protocol.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div></div><div>But that&#39;s beside the point. What I think the &quot;`allValues` should be allowed to be infinite&quot; suggestion misses is that one of `ValueEnumerable`&#39;s semantics is that it&#39;s not only theoretically *possible* to enumerate all the values, but actually *reasonable* to do so. This is more slippery and subjective than most protocol semantics, but I don&#39;t think that should disqualify it. There are plenty of places in the standard library where we make judgment calls like this. For instance, the decision that `Optional` should not conform to `Collection` is a similar judgment call: `Optional` could easily meet all of the formal requirements of a `Collection`, but we chose not to do it because we decided it didn&#39;t make *subjective* sense.</div><div><br></div><div>Some simple enums could not be reasonably conformed to `ValueEnumerable`; for instance, there&#39;s little sense in conforming an `Error` enum, because you&#39;re unlikely to need to discover all the possible errors expressed by a type at runtime. Some non-simple enums could be reasonably conformed to `ValueEnumerable`; `Bool` is an obvious example.</div><div><br></div><div>Some types, of course, fall into a gray area. `Int8` is fairly reasonable, but larger integer types get increasingly unreasonable until, by `Int64`, we reach types that would take decades to enumerate. Where the line should be drawn is a matter of opinion. (My opinion, to be clear, is that we shouldn&#39;t conform any of them; if someone really wants to do it, they can add a retroactive conformance.)</div></div></div></blockquote><div><br></div><div>Whether or not to *conform* a type to a protocol can certainly be a judgment call, and there are many places where that happens in the standard library; I suppose it&#39;s accepted in part because someone who disagrees can add a retroactive conformance where there isn&#39;t one, as you say.</div><div><br></div><div>But that is not solely the task before us, nor the criticism here.</div><div><br></div><div>My problem is that the semantics of your proposed protocol are slippery and subjective, as you acknowledge, and (as you&#39;ll see here and below) that is to be assiduously avoided in the standard library. As to your own example, there is no question whether `Optional` could fulfill the semantic requirements of conformance to `Collection`: the semantics defined on that protocol are such that there can be no disagreement that `Optional` does in fact meet the requirements. The judgment call is whether it&#39;s wise to conform or not, but the protocol&#39;s semantic requirements are anything but &quot;slippery.&quot;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class="gmail-"><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">As proposed, &quot;`ValueEnumerable`...indicate[<wbr>s] that a type has a finite, enumerable set of values&quot;; now, we have the constraint that the type merely must have an upper bound in terms of memory referenced. Brent just wrote that he might later propose to extend `ValueEnumerable` to `Bool` and `Optional`, but theoretically and practically speaking it appears that it can correctly be extended to any type in the standard library that is not a `Sequence`, and with minimal effort even `Collection` types of fixed size (e.g., CollectionOfOne&lt;T&gt; with the right constraints as to the generic type T).</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><br></div></span><div><div>Sure, but theoretically speaking, we could synthesize a `Comparable` implementation for all classes which compared them by address. This implementation would be totally correct, would fulfill all of the requirements of the protocol it was conforming to, and would usually be meaningless. So we don&#39;t.</div></div></div></div></blockquote><div><br></div><div>No, actually, you are incorrect about this example. We don&#39;t have such an implementation not because of some judgment that it&#39;s &quot;meaningless&quot; but because the documented semantics of `Equatable` unambiguously prohibit it: that is, it is not theoretically correct to do so. I refer you to the section in the `Equatable` documentation titled &quot;Equality is Separate From Identity,&quot; which begins: &quot;The identity of a class instance is not part of an instance’s value.&quot; Since `Comparable` refines `Equatable`, comparison by address would violate the clearly stated semantic requirements of the protocol.</div><div><br></div><div>Again, my criticism of your proposed design is precisely that it lacks semantic requirements such as this. Both this example, and the `Optional` example you give above in trying to demonstrate that it&#39;s all right to have ambiguity in protocol semantics, actually show that the standard library goes to great lengths not to leave that ambiguity. We have an opportunity to do so by sticking closely to what&#39;s desired in terms of solving only problem A, not trying to generalize a solution to encompass all types for which values are &quot;reasonably enumerable&quot;--which is very, very flimsy as to semantics.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div><div></div><div>The fact that some types could be given a useless conformance to a protocol does not imply that the protocol shouldn&#39;t exist.</div></div><span class="gmail-"><br><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">First, &quot;ValueEnumerable&quot;-ness is neither universal to all enums (as those with associated types, indirect cases (think of all those tutorials about linked lists implemented as Swift enums), etc., are clearly not enumerable) nor unique as a property of enums,</div></blockquote><div><br></div></span><div>It&#39;s absolutely true that not all enums should be enumerable, and also true that many non-enums should be enumerable. That&#39;s precisely why the protocol is not `CaseEnumerable` and the property is not `allCases`.</div></div></div></blockquote><div><br></div><div>Rather, I think that&#39;s precisely why problem A is only *kind of* a subset of problem B and why we should be solving only problem A, which is strongly motivated, not problem B. The example of an enum with cases having an associated type of another enum only reinforces the idea that &quot;all values&quot; and &quot;all cases&quot; are actually sometimes not the same thing for an enum.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class="gmail-"><br><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">yet this proposal first makes a large generalization of the proposed protocol&#39;s semantics when the stated motivation is only about enums,</div></blockquote><div><br></div></span><div>Do you disagree that there are many types which are not enums, but which—like the enums we are trying to address with this proposal—it is also reasonable to want to retrieve all values of? Or do you think we have missed important aspects of these types by not deeply analyzing them? Or are you simply criticizing how this part of the proposal was drafted, despite believing that its conclusion is correct?</div></div></div></blockquote><div><br></div><div>I think that many important issues related to the general question of types being enumerable (problem B) have not been deeply analyzed, and that you have proposed a solution to problem B where the motivation presented is only for problem A, and that problem A is only a kind of subset of problem B which does not engage the same panoply of difficult issues and may well have a different ideal solution than that for problem B.</div><div><br></div><div>In other words, I think your proposal correctly states a problem (A) with strong motivation, attempts to solve a related problem (B) with no good motivation for the switch (from A to B), and proposes a solution (for B) which is expedient rather than deeply correct with the attempted justification that the original problem (A) needs to be solved right away.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class="gmail-"><br><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">then proceeds only to implement protocol conformance for enums.</div></blockquote><div><br></div></span>I think it&#39;s more accurate to say that it &quot;only synthesizes a default implementation for simple enums&quot;. This is for three reasons:</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>1. Simple enums will probably be the most common conforming types, even if they aren&#39;t the only ones.</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>2. We can very easily synthesize an implementation which uses private APIs to return an `Int`-indexed and zero-based `RandomAccessCollection`, is highly optimized, and is forward-compatible. That is, for this subset of types and no others, we can implement a no-compromises, ideal implementation using special knowledge.</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>3. We are only confident that we know enough about the type to synthesize its implementation when it&#39;s a simple enum.</div><div><div><br></div><div>More on that last point: Enums explicitly list all of the valid values in the source code. By contrast, a struct definition often permits values which are not actually valid because Swift&#39;s type system is not rich enough to conveniently express the constraints on their properties. For example, in these types:</div><div><br></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>struct PlayingCard: ValueEnumerable {</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>enum Suit: ValueEnumerable {</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                        </span>case hearts, spades, diamonds, clubs</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>}</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span></div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>var suit: Suit</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">                </span>var rank: Int</div><div><span class="gmail-m_2640090446032120583Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><div><br></div><div>The compiler can correctly synthesize `PlayingCard.Suit.allValues` because all of its constraints are specified in code. By contrast, the compiler cannot know that `rank` must be between 1 and 13, so if it tried to synthesize `PlayingCard.allValues`, it would contain invalid values.</div><div><br></div><div>These limitations are quite common in the types of code synthesis we&#39;ve introduced so far. For example, we only synthesize an `Equatable` conformance if all the types involved are themselves `Equatable`; that&#39;s not because `Equatable` is only applicable to those types, it&#39;s just that we can&#39;t be reasonably sure of the desired semantics. The limitation of `ValueEnumerable` synthesis to simple enums is similar.</div><span class="gmail-"><div><br></div><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Second, the collection of all values is properly just the type and not a property of the type, for the reasons outlined above.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><br></div></span><div>Okay, let&#39;s say that&#39;s true. Is that the only or best way to express it?</div></div></div></blockquote><div><br></div><div>No, in need not be the only or the best way, but for the reasons given above it should be one of the ways.</div><div><br></div><div>In other words, suppose you believe that `allValues` is the best spelling. Fine. But something is wrong if `type(of: MyType.allValues) != type(of: MyType.self) || MyType.allValues != MyType.self`.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class="gmail-"><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">So far, the justification I have heard for ignoring this objection is that (a) lots of people want the specific use case of knowing all the cases of an enum; and (b) a complete design which makes metatypes conform to `Collection` is not feasible for Swift 5. But that, in my view, cannot justify the _permanent_ inclusion (with ABI stability) of a protocol whose semantics apply to all non-`Sequence` types, littering the standard library and untold many other libraries with this conformance for the sake of having something done for Swift 5.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><blockquote type="cite"><br></blockquote></div><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">My suggestion was, and is: if the motivation is to enumerate all the cases of an enum, deliver the best possible design for the specifically motivated use case rather than trying to deliver the most easy-to-implement design for the most general use case. In other words, give properly conformed enums (e.g. `enum MyEnum : Enumerable`--and I do suggest shortening the name, since what&#39;s enumerable is &quot;the set of all values&quot; == &quot;the type&quot;) the synthesized ability to have all cases enumerated by iterating over the metatype: `for case in MyEnum.self { ... }`. Add as much other `Collection` functionality as can be implemented in the Swift 5 timeframe, starting with the most pressing based on the motivating use case. Then deliver more and more of the best possible design with each version of Swift as engineering resources permit.</div></blockquote><br></span></div><div>There is nothing wrong with the proposed design. It&#39;s a good design, and depending on one&#39;s priorities, it&#39;s arguably the *best* design. That it&#39;s feasible to deploy today is just icing on the cake.</div></div></blockquote><div><br></div><div>It may be the most feasible design for solving problem B, and maybe even the best design, but in my view it&#39;s not correct if `MyType.allValues != MyType.self`. But crucially, even if you don&#39;t buy that argument, solving problem B is not appropriately motivated, and the best design for solving problem B may not be that for solving problem A, and I believe that we ought to focus on the latter.</div></div><br></div></div>