<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">I missed that sorry.<div><br></div><div>I think it will find other uses and therefore should be ValueEnumerable. <br><br><div id="AppleMailSignature">-- Howard.</div><div><br>On 11 Jan 2018, at 6:36 pm, Paul Cantrell <<a href="mailto:cantrell@pobox.com">cantrell@pobox.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div><blockquote type="cite" class=""><div class="">On Jan 11, 2018, at 7:28 PM, Howard Lovatt <<a href="mailto:howard.lovatt@gmail.com" class="">howard.lovatt@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class="">I am in favour of a protocol that you have to explicitly declare, it feels much more like Swift to me. For example you have to say Equatable explicitly. </div></div></blockquote><div><br class=""></div><div>Howard — Either you’ve missed something or I have. I didn’t view requiring types to explicitly declare conformance as being up for debate at all.</div><div><br class=""></div><div>The question I was weighing on it — what I thought Chris and Brent were discussing — was whether this new protocol should be used narrowly for cases of enums without associated types (which Chris favors), or whether it should find more broad use to mean “type which can enumerate all of its possible values” (which Brent finds interesting with caveats). This question has a bearing on whether the protocol’s name should be CaseEnumerable or ValueEnumerable.</div><div><br class=""></div><div>In either case, the conformance is always explicitly declared; the compiler merely synthesizes the implementation for enums without associated types.</div><div><br class=""></div><div>I think?</div></div><div class=""><br class=""><blockquote type="cite" class=""><div dir="auto" class=""><div class="">As a contra example in Java it feels natural that the compiler just provides the functionality because that is consistent across the language, you don’t declare something as equatable and you don’t tell the compiler that you want the values array generating. </div><div class=""><br class=""></div><div class="">‘Horses for courses’, this is what Swift does. </div><div class=""><br class=""></div><div class="">As a more hard-core example, suppose you want to use statics as an enum like construct, e.g.:</div><div class=""><br class=""></div><div class=""> struct Ex: ValueEnumerable {</div><div class=""> let x1: Int</div><div class=""> let x2: Int</div><div class=""> init(x1: Int, x2: Int) { self.x1 = x1, self.x2 = x2 }</div><div class=""> static let allValues = [x1, x2]</div><div class=""> }</div><div class=""><br class=""></div><div class="">Perhaps the above Ex started as an enum but was changed to a struct during enhancements to the program because the values of x1 and x2 are now read in rather than constants. <br class=""><br class=""><div class="">-- Howard.</div><div class=""><br class="">On 11 Jan 2018, at 5:21 pm, Paul Cantrell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 10:21 PM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Brent, thanks for the detailed response, one question about it:<br class=""><br class=""><blockquote type="cite" class="">On Jan 10, 2018, at 3:06 AM, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">But that's beside the point. What I think the "`allValues` should be allowed to be infinite" suggestion misses is that one of `ValueEnumerable`'s semantics is that it's not only theoretically *possible* to enumerate all the values, but actually *reasonable* to do so.<br class=""></blockquote>...<br class=""><blockquote type="cite" class="">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't conform any of them; if someone really wants to do it, they can add a retroactive conformance.)<br class=""></blockquote><br class="">I’m not sure which way you’re arguing here, but that’s ok. :-)<br class=""><br class="">In my opinion, while I can see where you are coming from (that it could be “reasonable” to allow random types to be ValueEnumerable) I don’t see what the *utility* or *benefit* that would provide.<br class=""><br class="">If we went with a simpler design - one that named this CaseEnumerable and .allCases - we would be heavily biasing the design of the feature towards enum-like applications that do not have associated types. This is “the” problem to be solved in my opinion, and would lead to a more clear and consistently understood feature that doesn’t have the ambiguity and “gray areas” that you discuss above. Given this bias, it is clear that infinite sequences are not interesting.<br class=""><br class="">Of course it would certainly be *possible* for someone to conform a non-enum-like type to CaseEnumerable, but that would be an abuse of the feature, and not a "gray area”. <br class=""><br class=""><br class="">Is there some specific *utility* and *benefit* from creeping this feature beyond “enumerating cases in enums that don’t have associated types”? Is that utility and benefit large enough to make it worthwhile to water down the semantics of this protocol by making it so abstract?<br class=""></div></div></blockquote></div><br class=""><div class="">I gave an example in my review of an enumerable thing where the items are analogous to cases but are not actually cases, and where I thought `allCases` would cause confusion but `allValues` would make sense:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">On Jan 10, 2018, at 10:22 AM, Paul Cantrell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</blockquote></div><div class=""><blockquote type="cite" class=""><br class=""></blockquote></div><div class=""><div class="" style="font-family: HelveticaNeue;"></div></div><blockquote type="cite" class=""><div class=""><div class="" style="font-family: HelveticaNeue;">Contra Chris, I slightly prefer ValueEnumerable, because it extends to situations where we still want to enumerate a fixed set of possibilities which don’t strictly correspond to enum cases but still have that sort of flavor. For example, one might want:</div><div class="" style="font-family: HelveticaNeue;"><br class=""></div><div class="" style="font-family: HelveticaNeue;"><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">enum</span> SideOfBody</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">case</span> left</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">case</span> right</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(88, 126, 168); background-color: rgb(255, 255, 255);"><span class="" style=""> </span><span class="" style="color: rgb(50, 62, 125);">enum</span><span class="" style=""> Limb: </span>ValueEnumerable</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">case</span> arm(<span class="" style="color: rgb(88, 126, 168);">SideOfBody</span>)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">case</span> leg(<span class="" style="color: rgb(88, 126, 168);">SideOfBody</span>)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(50, 62, 125);">static</span> <span class="" style="color: rgb(50, 62, 125);">let</span> allValues =</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> [</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(88, 126, 168);">arm</span>(.<span class="" style="color: rgb(88, 126, 168);">left</span>),</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(88, 126, 168);">arm</span>(.<span class="" style="color: rgb(88, 126, 168);">right</span>),</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(88, 126, 168);">leg</span>(.<span class="" style="color: rgb(88, 126, 168);">left</span>),</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> <span class="" style="color: rgb(88, 126, 168);">leg</span>(.<span class="" style="color: rgb(88, 126, 168);">right</span>)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> ]</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"> }</div></div><div class="" style="font-family: HelveticaNeue;"><br class=""></div><div class="" style="font-family: HelveticaNeue;">To my eyes, this code reads better than it would with CaseEnumerable / allCases.</div></div></blockquote><div class=""><br class=""></div><div class="">This raises a question related to Chris’s: what is the utility of having Limb conform to a protocol instead of just providing allValues ad hoc? Does CaseEnumerable / ValueEnumerable serve any purpose other than triggering special behavior in the compiler? Would the protocol ever be used as the type of something in code?</div><div class=""><br class=""></div><div class="">My answers, admittedly weak ones, are: (1) conventions are nice and consistency is nice, and (2) you never know how an abstraction might be used, but you do know that people will be angry when it should fit but doesn’t. I can’t come up with a more compelling or specific argument than those.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div><div class="">Paul</div><div class=""><br class=""></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></blockquote></div><br class=""></div></blockquote></div></body></html>