<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>