<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>I love the idea, and we tried it in Tyro, but the loss of structure is worrying. &nbsp;Plus, there isn't a way to specify that a protocol should apply only to an enum like there is with a class, nor that there should be proper kind constraints on implementors. &nbsp;e.g.</div><div><br></div><div>protocol EitherType {</div><div>&nbsp; associatedtype L</div><div>&nbsp; associatedtype R</div><div><br></div><div>&nbsp; var left : L? { get }</div><div>&nbsp; var right : R? { get }</div><div>}</div><div><br></div><div>This has a "valid" instance in every constructable type.</div><div><br></div><div>extension Int : EitherType {</div><div>&nbsp; public L = String</div><div>&nbsp; public R = NSGlyphGenerator</div><div><br></div><div>&nbsp; // Omitted for brevity</div><div>}</div><div><br></div><div>You get the picture.</div><div><br><div>~Robert Widmann</div></div><div><br>2016/01/26 12:36、T.J. Usiyan &lt;<a href="mailto:griotspeak@gmail.com">griotspeak@gmail.com</a>&gt; のメッセージ:<br><br></div><blockquote type="cite"><div><div dir="ltr">Is there a way that we can capture the desired parts of this proposal in a Protocol or Protocol-like structure? I'm thinking of some way to specify behavior that Enums possessing two cases which opt in can share. I understand that much of it can be done with a protocol now, what stands in the way of it being worthwhile?</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 26, 2016 at 12:30 PM, Developer via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><span></span></div><div><div><span></span></div><div><div><span></span></div><div><div><span class=""><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">I’m generally with Kevin on this. I’d classify actual-usage of `Either` as one of these three:</span></font></div><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)"><br></span></font></div><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- often: a rather poorly-named “Result” type (or a slight generalization thereof into the “fat optional”, e.g. instead of “X-or-nothing”, it’s “X-or-why-not-X?")</span></font></div></blockquote><div><br></div></span><div>You've described (T?, U?).&nbsp; This is not a "fat optional".&nbsp; And if we must use the term, then it's better to think of the reverse: an Optional is a thin Either.&nbsp; It is an Either that offers less information; a lobe of the type dedicated to () rather than an actual value.</div><span class=""><br><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- occasionally: a rather poorly-named, 2-way sum type (poorly-named b/c its convention won’t generalize to 3-way sums, or 4-ways sums, etc.)</span></font></div></blockquote><div><br></div></span><div>Good thing Either&lt;Either&lt;...&gt;, Either&lt;...&gt;&gt; works.</div><span class=""><br><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- rarely: a use that’s not really either of the above</span></font></div></blockquote><div><br></div></span><div>The ErrorT Monad Transformer?</div><div><br></div><div><span class=""><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">If there are some great uses of `Either` that:</span></font></div><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)"><br></span></font></div><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- (a) aren’t just Result/the “fat optional”&nbsp;</span></font></div></blockquote><div><br></div></span><div>The Validation type is just that.&nbsp; I'm going to draw one up and submit it to Swiftz.&nbsp; I'll let you know when that happens.</div><span class=""><br><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- (b) aren’t just a 2-way sum</span></font></div></blockquote><div><br></div></span>I don't understand? Are you literally asking for a non-sum-sum-type?<span class=""><br><br><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">- (c) support clean-and-*correct* implementations directly in terms of standard library functions (e.g., don’t force you to choose between "not actually halting iteration” and “re-implementing `reduce` just to get it right” )</span></font></div><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)"><br></span></font></div></blockquote><div><br></div></span><div><span style="background-color:rgba(255,255,255,0)">I can fix the example, but perhaps you've mistaken its inclusion in the proposal for a call to actually include it in the STL.&nbsp; It was just a romp through the capabilities of the type (see robrix's note about Continuation-Passing-isms).</span></div><span class=""><br><blockquote type="cite"><div><font color="#000000"><span style="background-color:rgba(255,255,255,0)">…then this proposal would be a lot stronger for including them.</span></font></div></blockquote><br></span></div><div>I agree somewhat.&nbsp; See my notes above.</div><br>~Robert Widmann</div><div><br>2016/01/26 8:52、plx via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; のメッセージ:<br><br></div><div><div class="h5"><blockquote type="cite"><div><div>I’m generally with Kevin on this. I’d classify actual-usage of `Either` as one of these three:</div><div><br></div><div>- often: a rather poorly-named “Result” type (or a slight generalization thereof into the “fat optional”, e.g. instead of “X-or-nothing”, it’s “X-or-why-not-X?")</div><div>- occasionally: a rather poorly-named, 2-way sum type (poorly-named b/c its convention won’t generalize to 3-way sums, or 4-ways sums, etc.)</div><div>- rarely: a use that’s not really either of the above</div><div><br></div><div>…which is why the early discussion veered into discussion of Result and structural unions.</div><div><br></div><div>Sticking to the topic at hand, I’ll actually pick on the `reduceEarly` function in the proposal (as currently-written), because to my eyes that's the only example that’s *perhaps* in that third category of interesting uses:</div><div><br></div><div>- on an infinite sequence it’s not a correct “early exit”; as-written, it’s a “never-exit” (defeating the purpose in situation you’d want it to actually, you know, exit early)</div><div>- even on a finite sequence, it’ll consume the entire sequence even on an “early-exit” (swift sequences are single-pass); this limits its usefulness as a building block for other constructs</div><div><br></div><div>These defects are, of course, easily fixable by manually writing-out the reduce logic; but, if you’re willing to write that out, the implementation cost will be about the same for a “direct" solution and the solution using `Either`, and given that, it’s not clear that *users* wouldn’t generally wind up preferring something like this:</div><div><br></div><div>enum IterationDecision {</div><div>&nbsp; Continue</div><div>&nbsp; ExitEarly</div><div>}</div><div><br></div><div>func reduceEarly&lt;T&gt;(initial: T, combine: (T,Generator.Element) -&gt; (T,IterationDecision)) -&gt; T {</div><div>&nbsp; var result: T = initial</div><div>&nbsp; for element in self {</div><div>&nbsp; &nbsp; let (update,decision) = combine(result,element)</div><div>&nbsp; &nbsp; switch decision {</div><div>&nbsp; &nbsp; &nbsp; case .Continue: result = update</div><div>&nbsp; &nbsp; &nbsp; case .EarlyExit: return update</div><div>&nbsp; &nbsp; }</div><div>&nbsp; }</div><div>&nbsp; return result</div><div>}</div><div><br></div><div>…where (as a user) the signature and the enumeration make its use essentially self-explanatory, versus, say, this:</div><div><br></div><div><div>func reduceEarly&lt;T&gt;(initial: T, combine: (T,Generator.Element) -&gt; Either&lt;T,T&gt;) -&gt; T {</div><div>&nbsp; var result: T = initial</div><div>&nbsp; for element in self {</div><div>&nbsp; &nbsp; switch combine(result,element) {</div><div>&nbsp; &nbsp; &nbsp; case let .Left(update): result = update</div><div>&nbsp; &nbsp; &nbsp; case let .Right(update): return update</div><div>&nbsp; &nbsp; }</div><div>&nbsp; }</div><div>&nbsp; return result</div><div>}</div></div><div><br></div><div>…where the user will likely have to check the documentation to see which of `.Left` and `.Right` means “early-exit” here (unless `Either`’s gone sufficiently-pervasive by then that such knowledge will be de rigueur).</div><div><br></div><div>If there are some great uses of `Either` that:</div><div><br></div><div>- (a) aren’t just Result/the “fat optional”&nbsp;</div><div>- (b) aren’t just a 2-way sum</div><div>- (c) support clean-and-*correct* implementations directly in terms of standard library functions (e.g., don’t force you to choose between "not actually halting iteration” and “re-implementing `reduce` just to get it right” )</div><div><br></div><div>…then this proposal would be a lot stronger for including them.</div><br><div><blockquote type="cite"><div>On Jan 26, 2016, at 12:27 AM, Developer via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div dir="auto"><div>Are you opposed to the name or the semantics?</div><div><br></div><div>I will not accept a revision that reduces the level of abstraction of the current proposal.&nbsp; I will, however, accept name changes.&nbsp; Result, though, I believe is out of the question.&nbsp; It strongly implies a common but pointed set of semantics that discourage thinking of this type as data and more as an alternative to throws.&nbsp; I do not wish to emphasize the error case, or the theoretical case, I wish to encourage the general case.&nbsp; We must remember that despite Rust's success, they do not have to live alongside an exceptions mechanism like Either does.<br><br><div>~Robert Widmann</div></div><div><br>2016/01/26 0:55、Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; のメッセージ:<br><br></div><blockquote type="cite"><div>




<div>There absolutely is a cost. `Result&lt;T&gt;` has a rather intuitive meaning. `Either&lt;T&gt;` has&nbsp;<i>no intuitive meaning whatsoever</i>. It says absolutely&nbsp;<i>nothing</i> about what it means beyond the fact that there are two potential values. As a result, it is a largely useless type whose sole redeeming feature is it allows developers to avoid having to define their own enum, but in most cases that aren't covered by Result&lt;T&gt; you actually&nbsp;<i>want</i> to define your own enum so you can attach meaning to the value.<br></div>
<div>&nbsp;</div>
<div>If it's not obvious, I'm very strongly against having a generic Either type, but I do want a Result&lt;T&gt; or Result&lt;T,E&gt;.<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard</div>
<div>&nbsp;</div>
<div>On Fri, Jan 22, 2016, at 10:22 PM, Developer via swift-evolution wrote:<br></div>
<blockquote type="cite"><div><div>My overwhelming concern, after having a conversation with Chris, is that implementing a Result&lt;T&gt; means we are strongly implying a particular semantics and use case when we could generalize and abstract for no cost but an extra generic parameter.&nbsp; In F#, Core.Choice can be used to build a Validation or Result monad, but the converse is impossible.<br></div>
<div>&nbsp;</div>
<div>~Robert Widmann<br></div>
</div>
<div><div>&nbsp;</div>
<div>2016/01/23 1:05、Rob Mayoff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; のメッセージ:<br></div>
</div>
<blockquote type="cite"><div><div dir="ltr"><div><div><blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>Just added a section of motivating examples to the Either proposal.&nbsp; Ping me if you have any more that I missed ('cause I'm sure I did miss a lot).<br></div>
<div>&nbsp;</div>
<div> <a href="https://github.com/typelift/swift-evolution/blob/either-or/proposals/0024-either.md#motivating-examples" target="_blank">https://github.com/typelift/swift-evolution/blob/either-or/proposals/0024-either.md#motivating-examples</a><br></div>
<div>&nbsp;</div>
</blockquote><div>&nbsp;</div>
<div>Your motivating examples (including all the projects you linked except "Any many more") overwhelmingly use the Either (or similar type) to represent success/failure. I'm not sure there's a single example where the names Left and Right actually make sense in the problem domain. I'm not 100% sure about func alternate in Madness/Alternation.swift. It definitely uses Left/Right to mean Failure/Result, but I couldn't tell if it also uses them as something else. Which makes those names all the more maddening.<br></div>
<div>&nbsp;</div>
<div>I checked my company's largest Scala project, which is over 300,000 lines. We use Scala's Try/Success/Failure in dozens of places. We use Either/Left/Right once, in a thrown-together report-generating script, which would probably have been written in awk or perl if it didn't need to read binary log files. (The ability of IntelliJ to reliably find all uses of a class or method is not to be underestimated. Hint hint, team Xcode.)<br></div>
<div>&nbsp;</div>
<div>I think a Result/Success/Failure type is warranted, but I'm very skeptical about generic Either/Left/Right.<br></div>
<div>&nbsp;</div>
</div>
</div>
</div>
</div>
</blockquote><blockquote type="cite"><div><div><span>_______________________________________________</span><br></div>
<div><span>swift-evolution mailing list</span><br></div>
<div><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br></div>
<div><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div>
</div>
</blockquote><div><u>_______________________________________________</u><br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote><div>&nbsp;</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" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></div></div></div></div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>
</div></blockquote></body></html>