<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">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.&nbsp;<div><br></div><div>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.&nbsp;</div><div><br></div><div>‘Horses for courses’, this is what Swift does.&nbsp;</div><div><br></div><div>As a more hard-core example, suppose you want to use statics as an enum like construct, e.g.:</div><div><br></div><div>&nbsp; &nbsp; struct Ex: ValueEnumerable {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; let x1: Int</div><div>&nbsp; &nbsp; &nbsp; &nbsp; let x2: Int</div><div>&nbsp; &nbsp; &nbsp; &nbsp; init(x1: Int, x2: Int) { self.x1 = x1, self.x2 = x2 }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; static let allValues = [x1, x2]</div><div>&nbsp; &nbsp; }</div><div><br></div><div>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.&nbsp;<br><br><div id="AppleMailSignature">-- Howard.</div><div><br>On 11 Jan 2018, at 5:21 pm, Paul Cantrell via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 10:21 PM, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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 &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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. &nbsp;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. &nbsp;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”. &nbsp;<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”? &nbsp;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 &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">enum</span>&nbsp;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);">&nbsp; &nbsp; &nbsp; {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">case</span>&nbsp;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);">&nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">case</span>&nbsp;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);">&nbsp; &nbsp; &nbsp; }</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="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(50, 62, 125);">enum</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;Limb:&nbsp;</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);">&nbsp; &nbsp; &nbsp; {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">case</span>&nbsp;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);">&nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">case</span>&nbsp;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);">&nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">static</span>&nbsp;<span class="" style="color: rgb(50, 62, 125);">let</span>&nbsp;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);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<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);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<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);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<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);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<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);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;]</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; }</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"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></body></html>