<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="NL-BE" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">David Alayachew<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Wed Jun 14 13:00:06 UTC 2023<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> Hello Rémi,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> To start off, Nothing is only going to take you a short distance. Nothing works decently enough for the type T. But for the Exception, Nothing will not work as a type parameter because the type parameter it is supposed
 to be matching is E, and E extends Exception. Nothing does not extend Exception (presumably), and even if it did, this would be a constantly growing problem that we do not want to put into the language. What if you need R to extend List\<String>, for example?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">This is a flawed understanding of the question that was asked. A 'Bottom type' ('Nothing' here) is a type that extends every other type and is not instantiatable.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Brian Goetz<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Wed Jun 14 17:50:53 UTC 2023<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> [...]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> What you are probably reacting to here is "but why does Fail have to say T, it doesn't use it."  And the answer is: "get over that, and then you're done." 
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">> You are trying to invent a new generics feature to avoid putting a `T` you don't use in your Error declaration.  But that T (and maybe E) are needed to unify the two under Result<T,E> -- just like in the second Haskell
 example above.  <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">A valid reason in my opinion to want a `nothing` type is that it would solve the issue of unchecked casts your solution will introduce.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">```<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">static Result<String> getContentOfFile(Path path) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    // simple mock implementation<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    if (!Files.exist(path)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        return new Fail<>(IOException("..."));<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    } else {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        return new Succ<>("Data");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">static Result<List<String>> getLinesOfFile1(Path path) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    return switch(getContentOfFile(path)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Succ<String>(var contents) -> new Succ<>(contents.lines().toList());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Fail<String> error -> (Result<List<String>>) error; // requires unchecked cast<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">static Result<List<String>> getLinesOfFile2(Path path) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    return switch(getContentOfFile(path)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Succ<String>(var contents) -> new Succ<>(contents.lines().toList());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Fail<String>(var error) -> new Fail<>(error); // requires redundant allocation<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">```<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">One maybe slightly better solution is to introduce an `into` method on `Fail` to hide the cast<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">```<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">record Fail<T>(Throwable t) extends Result<T> {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    public <R> Fail<R> into() {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        return (Fail<R>)this;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">static Result<List<String>> getLinesOfFile3(Path path) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    return switch(getContentOfFile(path)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Succ<String>(var contents) -> new Succ<>(contents.lines().toList());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">        case Fail<String> error -> error.into();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">```<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">In the end, once we get value types, `getLinesOfFile2` wont really be an issue, (maybe someone even makes an extra optimization for sealed types where all subclasses are value types). Additionally, like Dan Smith said,
 a bottom type would only be useful here if have declaration-site variance, which we don't have (*yet*).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Kind regards<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Robbe Pincket<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>