<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&#39;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?&quot;)</span></font></div></blockquote><div><br></div></span><div>You&#39;ve described (T?, U?).  This is not a &quot;fat optional&quot;.  And if we must use the term, then it&#39;s better to think of the reverse: an Optional is a thin Either.  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” </span></font></div></blockquote><div><br></div></span><div>The Validation type is just that.  I&#39;m going to draw one up and submit it to Swiftz.  I&#39;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&#39;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 &quot;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&#39;ve mistaken its inclusion in the proposal for a call to actually include it in the STL.  It was just a romp through the capabilities of the type (see robrix&#39;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.  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?&quot;)</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&#39;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&quot; 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>  Continue</div><div>  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>  var result: T = initial</div><div>  for element in self {</div><div>    let (update,decision) = combine(result,element)</div><div>    switch decision {</div><div>      case .Continue: result = update</div><div>      case .EarlyExit: return update</div><div>    }</div><div>  }</div><div>  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>  var result: T = initial</div><div>  for element in self {</div><div>    switch combine(result,element) {</div><div>      case let .Left(update): result = update</div><div>      case let .Right(update): return update</div><div>    }</div><div>  }</div><div>  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” </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 &quot;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.  I will, however, accept name changes.  Result, though, I believe is out of the question.  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.  I do not wish to emphasize the error case, or the theoretical case, I wish to encourage the general case.  We must remember that despite Rust&#39;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 <i>no intuitive meaning whatsoever</i>. It says absolutely <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&#39;t covered by Result&lt;T&gt; you actually <i>want</i> to define your own enum so you can attach meaning to the value.<br></div>
<div> </div>
<div>If it&#39;s not obvious, I&#39;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> </div>
<div>-Kevin Ballard</div>
<div> </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.  In F#, Core.Choice can be used to build a Validation or Result monad, but the converse is impossible.<br></div>
<div> </div>
<div>~Robert Widmann<br></div>
</div>
<div><div> </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.  Ping me if you have any more that I missed (&#39;cause I&#39;m sure I did miss a lot).<br></div>
<div> </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> </div>
</blockquote><div> </div>
<div>Your motivating examples (including all the projects you linked except &quot;Any many more&quot;) overwhelmingly use the Either (or similar type) to represent success/failure. I&#39;m not sure there&#39;s a single example where the names Left and Right actually make sense in the problem domain. I&#39;m not 100% sure about func alternate in Madness/Alternation.swift. It definitely uses Left/Right to mean Failure/Result, but I couldn&#39;t tell if it also uses them as something else. Which makes those names all the more maddening.<br></div>
<div> </div>
<div>I checked my company&#39;s largest Scala project, which is over 300,000 lines. We use Scala&#39;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&#39;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> </div>
<div>I think a Result/Success/Failure type is warranted, but I&#39;m very skeptical about generic Either/Left/Right.<br></div>
<div> </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> </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>