[External] : Re: Yielding blocks
Brian Goetz
brian.goetz at oracle.com
Sat Mar 5 21:11:02 UTC 2022
I certainly agree that blocks would need something to prefix them. I
don't necessarily object to the concept, but we have other,
higher-leverage activities I'd rather pursue instead right now.
On 3/4/2022 9:38 PM, Tagir Valeev wrote:
> For the record, I suggested a similar enhancement two years ago:
> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-March/002046.html
> The difference is that I think that explicit prefix, like `do { ... }`
> would be better. In particular, it helps to disambiguate between array
> initializer and block expression..
>
> With best regards,
> Tagir Valeev
>
> On Sat, Mar 5, 2022 at 12:36 AM Brian Goetz<brian.goetz at oracle.com> wrote:
>> The following was received on the -comments list.
>>
>> Summary: "Can we please have block expressions, you're almost there with the yielding block in switch expressions."
>>
>> My observations: There was some discussion around the time we did switch expressions about whether we wanted a general-purpose block expression; it was certainly clear that we were inventing a limited form of block expression, and the worst thing about what we did back then was open the door to block expressions a bit, raising the inevitable questions about "why not just throw open the door". While I can imagine wanting to open up on this at some point in the future, and am sympathetic to the notion that we want to express some things as expressions that currently require statements, I'm still not particularly motivated to throw open this door at this time.
>>
>>
>> -------- Forwarded Message --------
>> Subject: Yielding blocks
>> Date: Fri, 4 Mar 2022 01:22:19 +0200
>> From: Dimitris Paltatzidis<dcrystalmails at gmail.com>
>> To:amber-spec-comments at openjdk.java.net
>>
>>
>> Methods, ignoring their arguments, form 2 categories:
>> 1. Those that do not return a value (void).
>> 2. Those that do.
>>
>> Now, stripping away their signature, we get anonymous methods. Java supports
>> category 1, "blocks". They can be local, instance initializers or even
>> static.
>> On the other end, category 2 is missing. Consider the examples below of
>> trying
>> to initialize a local variable, with a complex computation.
>>
>> A. (Verbose and garbage producing)
>> Type a = ((Supplier<Type>) () -> {
>> .
>> .
>> return .. ;
>> }).get();
>>
>> B. (The hack, hard to reason)
>> Type a = switch (0) {
>> default -> {
>> .
>> .
>> yield .. ;
>> }
>> };
>>
>> C. (Does not exist)
>> Type a = {
>> .
>> .
>> yield .. ;
>> }
>>
>> All of them are equal in power, yet C is compact and readable. Of course, no
>> one will resort to A or B, instead they will compute in the same block as
>> the
>> variable in question (a). Unfortunately, that has a few drawbacks:
>> 1. Pollution of the block with temporary variables that won't be needed
>> further
>> down the line, and at the same time, prohibiting the usage of the same
>> name,
>> especially if they were final.
>> 2. Hard to reason where statements and computations start and end, without
>> resorting to comments.
>>
>> Now, with limited power we can have:
>>
>> D. (Legal)
>> Type a; {
>> .
>> .
>> a = .. ;
>> }
>>
>> Actually D has fewer characters than C, for small enough variable names. It
>> also
>> solves the pollution problems stated above. But, as already mentioned, it
>> lacks
>> in power. We can't use it in places where only 1 statement is permitted,
>> like
>> computing the parameter of a method inside its parenthesis.
>>
>> With C, we can even initialize instance variables (or static) that require
>> multiple statements, without resorting to an instance initializer block.
>> Basically, computing a value ad-hoc that fits everywhere.
>>
>> The block right of the arrow -> of a switch case is basically it. It just
>> needs
>> a promotion to stand on its own.
More information about the amber-spec-observers
mailing list