<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">Thanks for the well-reasoned
        thoughts.  <br>
        <br>
        Indeed, the monadic approach is more constraining and explicit
        (and has the accidental complexity of nominality, in that my
        Either won't interoperate with yours.)  Where I think we'd find
        differences of opinion is whether those constraints are a bug or
        a feature.  I agree that improving the ability to abstract over
        exception types is the more Java-like solution.<br>
        <br>
        In reality, though, people will want both.  A good analogy is
        Streams.  For the kinds of computations streams is good for --
        and that's a lot -- people love it, it is clear, concise,
        reliable, and performant.  But it would be silly to say "let's
        get rid of all the control flow constructs in Java, and just do
        everything with streams" -- streams just isn't up to that task,
        and that's OK.  It's a flexible tool, and its good for what it
        is good for.<br>
        <br>
        Unsurprisingly, Either is good in the same ways -- for some
        kinds of constrained composition, you can just >>= your
        way along and express things clearly and safely.  But just as we
        don't want to do all our computation with streams, we won't want
        to do all our computation this way either, and will want to
        punch out to a more imperative mechanism.  <br>
        <br>
        Finally, I'll point out that Streams, because of its inherent
        constraints, would work fine in either world, so we can't
        extrapolate very much from how it would work there.  <br>
        <br>
        Cheers,<br>
        -Brian<br>
      </font></font><br>
    <div class="moz-cite-prefix">On 3/7/2023 11:05 AM, Holo The Sage
      Wolf wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAKswmE4R6S405LLa+6YoYDAAo8y+CiRVitsWEWes7PQ2ip793Q@mail.gmail.com">
      
      <div dir="ltr">I do want to write for the record my reasons to
        prefer the Effect system approach in the hope to convince you
        and others about my view, but I do acknowledge that this
        discussion is still far, and the relevance of my words now may
        only appear when the work on patterns and string templates will
        finalize, so unless there is a good reason I will not continue
        the discussion further after this message.
        <div><br>
        </div>
        <div>Effect System enables a code style that is easier to
          follow, it hides the "unimportant" parts (unimportant to the
          logic) somewhere in the background and allows you to write as
          if there are no effects to your code (I am aware of the irony
          here). Of course it does in the end force you to handle the
          effects, but you can handle those effects orthogonally to your
          actual logic. Unlike the Monadic system which requires you to
          work in "the monad world" as described a lot by Haskell
          developers, you need to carry your Either wraps everywhere
          till you handle them.</div>
        <div><br>
        </div>
        <div>In addition, I believe that there is another argument for
          the Effect system specifically for Java: there is a difference
          between a language feature and a datatype, unlike some other
          languages Java is built heavily over 3rd party libraries, if
          we look at the big libraries out there we would find that a
          lot of them are using custom Either (and friends) classes,
          this cause that composing those libraries is not as simple as
          we would want it to be, by making a language feature that
          handle those cases <i>well</i>, there will be a much larger
          intersection between the APIs (the "<i>well"</i>  in the
          previous sentence is important, I want to believe that it is
          possible to do that in Java)</div>
        <div><br>
        </div>
        <div>Finally I want to link 2 more projects.</div>
        <div><br>
        </div>
        <div>Apart from Koka there is also [Effekt](<a href="https://urldefense.com/v3/__https://effekt-lang.org/__;!!ACWV5N9M2RV99hQ!Mfpw93goar8q9RTDRHUzTwShJx-j9c1yG0yNoeKm5PAcf_eUvgN0JS57Ou_dgr7E0c86MMVKHwb_tRs_3w$" moz-do-not-send="true">https://effekt-lang.org/</a>), I like
          the way Koka handles things better, but Effekt is another
          language that has Effects as its core mechanic.</div>
        <div><br>
        </div>
        <div>Apart from Effect systems, there is also the idea of
          Coeffect systems, for a similar reasons as above, I really
          like a Coeffect type system and want to link to [my coeffect
          system in Java](<a href="https://urldefense.com/v3/__https://github.com/Holo314/Coeffect__;!!ACWV5N9M2RV99hQ!Mfpw93goar8q9RTDRHUzTwShJx-j9c1yG0yNoeKm5PAcf_eUvgN0JS57Ou_dgr7E0c86MMVKHwZ7yoKdEw$" moz-do-not-send="true">https://github.com/Holo314/Coeffect</a>)
          (I didn't have much time to work on it lately, but currently I
          am fighting Java's compiler plugins API to make it a stand
          alone plugin, as well as in the process of implementing custom
          type system in the annotation to enable stuff similar to what
          I wrote in my previous mail).</div>
        <div><br>
        </div>
        <div>Again, I would love to discuss further when it is more
          relevant. </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Mar 7, 2023 at 4:56 PM
          Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div> <font size="4"><font face="monospace">Thanks for the
                link to Koka.  <br>
                <br>
                Indeed, I spent many hours prototyping something exactly
                like this for Streams back in the Java 8 days, as an
                extension to one of the "exception transparency"
                proposals that came up at the time.  As you point out,
                in libraries like streams, a throwing lambda passed as a
                parameter "pollutes" the type of the returned stream,
                since the lambda is incorporated into the stream and may
                be invoked by a later operation, and therefore might be
                thrown from that later operation.  <br>
                <br>
                This basically asks the generic type system to have type
                variables to track effects as well as types (see, e.g.,
                "Type and Effect Systems", Nielsen and Nielsen.)  <br>
                <br>
                As your example shows, it is possible to do this with
                (a) some form of variadic generics and (b) some
                algebraic operations on variadic parameters (e.g.,
                concatenating, unioning, differencing).  It also means
                that generic classes like Stream have to carry around
                additional type variables describing their exceptions
                (effects), and those tvars are "different" from ordinary
                tvars.  <br>
                <br>
                Our conclusion at the time we did this experiment is
                that, while the approach is viable, annotation burden on
                library authors is high, and this burden flows through
                to clients as well.  (Even if we allow use sites to
                elide the exception information, so they can say
                Stream<String> rather than Stream<String,
                ExceptionGoop>, it still flows into the docs and
                error messages.)  It also makes generics "even more
                complex" (and people still complain generics are too
                complex.)  <br>
                <br>
                So the outcome of this experiment was "yes, it can be
                made to work, but no, we don't think putting into Java
                at this time is likely to be seen entirely positively."<br>
                <br>
                <blockquote type="cite">
                  <p style="margin:0px 0px 1.2em">While I do believe
                    that the actual solution will require much more
                    thought than this (e.g. deconstruction of generic
                    sums to be able to handle specific exceptions and
                    remove those exceptions from the final union type of
                    exceptions), this is a showcase that a nice and
                    composable checked exceptions works even without
                    Monadic types.</p>
                </blockquote>
                <br>
                Indeed. The need for asymmetric difference as one of the
                algebraic operations on effect variables is one of those
                surprises that bites you the first time you encounter
                it.  <br>
                <br>
                <blockquote type="cite">
                  <p style="margin:0px 0px 1.2em">I find this direction
                    much nicer than using Either everywhere.</p>
                </blockquote>
                <br>
                I am not sure whether I do or not, which is one reason
                we've not done either yet...<br>
                <br>
                <br>
              </font></font><br>
            <div>On 3/7/2023 8:24 AM, Holo The Sage Wolf wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">
                <div>
                  <p style="margin:0px 0px 1.2em">This is a continuation
                    of this <a href="https://mail.openjdk.org/pipermail/amber-dev/2023-March/007849.html" target="_blank" moz-do-not-send="true">thread</a>,
                    unfortunately I only joined the mailing list, so I
                    can’t reply to it so I apologize for opening a new
                    thread.</p>
                  <p style="margin:0px 0px 1.2em">I want to point to <a href="https://urldefense.com/v3/__https://koka-lang.github.io/koka/doc/book.html*why-effects__;Iw!!ACWV5N9M2RV99hQ!Mfpw93goar8q9RTDRHUzTwShJx-j9c1yG0yNoeKm5PAcf_eUvgN0JS57Ou_dgr7E0c86MMVKHwaBnm23ow$" target="_blank" moz-do-not-send="true">Koka</a>,
                    Koka is a language built upon the concept of Effect,
                    a generalization of how Java treats checked
                    exceptions (and similarly to what Brian Goetz said
                    about how Checked exceptions are equivalent to
                    Either, general Effect system is equivalent to full
                    monadic type system).</p>
                  <p style="margin:0px 0px 1.2em">The language is very
                    interesting and worth reading about, but the
                    relevant part is their Polymorphic Effects, which
                    allow you to extend the effects. In Java pseudo
                    code, it means that the following is valid:</p>
                  <pre style="font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;white-space:pre-wrap;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248);display:block">
<span>@FunctionalInterface</span>
<span style="color:rgb(51,51,51);font-weight:bold">public</span> <span><span style="color:rgb(51,51,51);font-weight:bold">interface</span> <span style="color:rgb(68,85,136);font-weight:bold">EPredicate</span><<span style="color:rgb(68,85,136);font-weight:bold">T</span>, <span style="color:rgb(68,85,136);font-weight:bold">E</span> <span style="color:rgb(51,51,51);font-weight:bold">extends</span> <span style="color:rgb(68,85,136);font-weight:bold">Throwable</span>> </span>{
    <span><span style="color:rgb(51,51,51);font-weight:bold">boolean</span> <span style="color:rgb(153,0,0);font-weight:bold">test</span><span>(T t)</span> <span style="color:rgb(51,51,51);font-weight:bold">throws</span> E</span>;
}

<span>@FunctionalInterface</span>
<span style="color:rgb(51,51,51);font-weight:bold">public</span> <span><span style="color:rgb(51,51,51);font-weight:bold">interface</span> <span style="color:rgb(68,85,136);font-weight:bold">EConsumer</span><<span style="color:rgb(68,85,136);font-weight:bold">T</span>, <span style="color:rgb(68,85,136);font-weight:bold">E</span> <span style="color:rgb(51,51,51);font-weight:bold">extends</span> <span style="color:rgb(68,85,136);font-weight:bold">Throwable</span>> </span>{
    <span><span style="color:rgb(51,51,51);font-weight:bold">boolean</span> <span style="color:rgb(153,0,0);font-weight:bold">test</span><span>(T t)</span> <span style="color:rgb(51,51,51);font-weight:bold">throws</span> E</span>;
}

<span style="color:rgb(51,51,51);font-weight:bold">public</span> <span><span style="color:rgb(51,51,51);font-weight:bold">class</span> <span style="color:rgb(68,85,136);font-weight:bold">EStream</span><<span style="color:rgb(68,85,136);font-weight:bold">V</span>,<span style="color:rgb(68,85,136);font-weight:bold">E</span> <span style="color:rgb(51,51,51);font-weight:bold">extends</span> <span style="color:rgb(68,85,136);font-weight:bold">Throwable</span>> </span>{
    <span style="color:rgb(51,51,51);font-weight:bold">public</span> <EX extends Throwable> EStream<V, (E|EX)> filter(EPredicate<? <span style="color:rgb(51,51,51);font-weight:bold">super</span> T, (E|EX)> predicate) {
        ...
    }

    <span style="color:rgb(51,51,51);font-weight:bold">public</span> <EX extends Throwable> <span><span style="color:rgb(51,51,51);font-weight:bold">void</span> <span style="color:rgb(153,0,0);font-weight:bold">forEach</span><span>(EConsumer<? <span style="color:rgb(51,51,51);font-weight:bold">super</span> T, (E|EX)</span>> action) <span style="color:rgb(51,51,51);font-weight:bold">throws</span> E, EX </span>{
        ...
    }
}
</code></pre>
                  <p style="margin:0px 0px 1.2em">Which allows you to
                    have a fluent composition without losing the
                    fine-grained checked exceptions:</p>
                  <pre style="font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;white-space:pre-wrap;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248);display:block">
<span><span style="color:rgb(51,51,51);font-weight:bold">public</span> <span style="color:rgb(51,51,51);font-weight:bold">static</span> <span style="color:rgb(51,51,51);font-weight:bold">void</span> <span style="color:rgb(153,0,0);font-weight:bold">main</span><span>(string[] args)</span> <span style="color:rgb(51,51,51);font-weight:bold">throws</span> FileNotFoundException, IllegalAccessException, SQLException </span>{
    myEStream.filter(v -> ...) <span style="color:rgb(153,153,136);font-style:italic">// something that throws FileNotFoundException</span>
                     .filter(v -> ...) <span style="color:rgb(153,153,136);font-style:italic">// something that throws IllegalAccessException</span>
                     .forEach(v -> ...); <span style="color:rgb(153,153,136);font-style:italic">// something that throws SQLException</span>
}
</code></pre>
                  <p style="margin:0px 0px 1.2em">This also makes the
                    type system of the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">throws</code>
                    clause a subset of the generics type system.</p>
                  <p style="margin:0px 0px 1.2em">While I do believe
                    that the actual solution will require much more
                    thought than this (e.g. deconstruction of generic
                    sums to be able to handle specific exceptions and
                    remove those exceptions from the final union type of
                    exceptions), this is a showcase that a nice and
                    composable checked exceptions works even without
                    Monadic types.</p>
                  <p style="margin:0px 0px 1.2em">I find this direction
                    much nicer than using Either everywhere.</p>
                </div>
                <div><span>-- </span><br>
                  <div dir="ltr">
                    <div dir="ltr">Holo The Wise Wolf Of Yoitsu</div>
                  </div>
                </div>
              </div>
            </blockquote>
            <br>
          </div>
        </blockquote>
      </div>
      <br clear="all">
      <div><br>
      </div>
      <span class="gmail_signature_prefix">-- </span><br>
      <div dir="ltr" class="gmail_signature">
        <div dir="ltr">Holo The Wise Wolf Of Yoitsu</div>
      </div>
    </blockquote>
    <br>
  </body>
</html>