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.go...@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 <dcrystalma...@gmail.com> > To: amber-spec-comme...@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.