do expression
Mateusz Romanowski
romanowski.mateusz at gmail.com
Tue Mar 24 16:07:57 UTC 2020
Hi All,
I have seen your discussion regarding using a new expression to place
field's initialization block with the field instead of in class/instance
initializer.
While I understand reluctance to introduce new keywords, there is the idea
of using lazy static final fields [1] instead of complicated class static
initializers.
I think that scenario might also need a new expression more.
Has there been any thoughts how to declare source-code static final field
to be translated into a LazyValue backed by condy?
Moreover, has there been any thoughts how to declare such field to throw
checked exception on field read when its initialization might?
Sorry if the issue has already been discussed.
Thanks,
Mateusz Romanowski
[1] https://bugs.openjdk.java.net/browse/JDK-820996
On Tue, Mar 24, 2020 at 4:56 AM John Rose <john.r.rose at oracle.com> wrote:
> The keyword “do” is so short and sweet, and so under-used,
> that it’s tempting to give it a new job.
>
> But I don’t think this job is important enough. It’s just making
> a little sugar for something you can express already with switch.
>
> As Guy says there are many ways to wrap a block in an expression,
> if we should want to do this. If we use a keyword, I would think
> it should be a larger keyword than “do”, just to make it more
> visible. Or, if invisibility is OK, perhaps no keyword at all is
> OK, just “({ x })”: But that clearly shows the problems with
> making the shift between statement and expression go almost
> invisible; and “do” is like that also, just two characters.
> We went round and round on these issues with lambdas,
> because they are similar. It takes a long while to settle on
> just the right syntax to (a) read well, (b) not be too noisy,
> and (c) not be too invisible either.
>
> Let’s keep “do” in reserve. There are much deeper things we can
> eventually “do” with that keyword. In particular, if we open
> up Java to allow extended execution modes, such as parallel
> or differentiable or symbolic or side-effect-controlled, we will want
> a concise way to mark the blocks of code which are to be “done”
> in an extended execution mode. For my money, that’s worth
> “doing up” with a pretty keyword.
>
> Before anyone asks, no I don’t have a specific proposal for
> such a thing. A first draft, IMO, will use something like
> lambda cracking (or maybe a clumsier form of quoting)
> to work out the details of how to abstract over evaluation
> modes, and apply them independently of the code snippets
> themselves. There’s a lot of experimentation to work
> through first, with no sugar anywhere, before we would
> be confident of the correct degrees of freedom, the
> different ways to “do” code.
>
> I “do” have an unspecific proposal: Look at F# computation
> expression, and Haskell “do” syntax. They cannot be spliced
> whole-sale into Java without many adjustments, but they are
> examples of what I mean by abstracting apart mode of computation
> from code-structure of computation. What’s required are two
> chunks of ordinary-looking code, one to supply local rules for
> evaluation, and one to execute, non-standardly, under the
> local rules. I have no idea (1) what the looks in in detail
> for Java, and (2) what the sugary syntax would be, but that’s
> the sort of juicy feature where little old “do” might come
> into its own, something like (OK, syntax) “using (x) do y”.
>
> — John
>
> On Mar 23, 2020, at 7:23 PM, Tagir Valeev <amaembo at gmail.com> wrote:
> >
> > Hello!
> >
> > Now we have a legal way to execute several statements within an
> expression, yielding the result with a yield statement. This could be done
> via `switch` expression.
> >
> > Sometimes it's desired to do this without any switch. One may abuse the
> switch expression feature writing `switch(0) { default -> { ... code block
> ending with 'yield' }}`.
> >
> > How about creating a special syntax for such kind of expression. It
> could look like `do { ... code block ending with 'yield' }`?
> >
> > E.g. consider:
> >
> > class X {
> > static final String field;
> >
> > // now we are forced to split field declaration and initialization
> > // also initializer could be long and it could be not evident that its
> main purpose
> > // is to initialize the field
> > static {
> > try {
> > field = initializeField();
> > }
> > catch(CheckedException e) {
> > throw new RuntimeException(e);
> > }
> > }
> > }
> >
> > Since Java 14 we can write
> >
> > class X {
> > // field declaration and initialization in the same place: easier to
> navigate through code
> > // though we are abusing the switch expression
> > static final String field = switch(0) { default -> {
> > try {
> > yield initializeField();
> > }
> > catch(CheckedException e) {
> > throw new RuntimeException(e);
> > }
> > }};
> > }
> >
> > It could be like
> >
> > class X {
> > // concise syntax. Now we know that the main block purpose
> > // is to initialize the field
> > static final String field = do {
> > try {
> > yield initializeField();
> > }
> > catch(CheckedException e) {
> > throw new RuntimeException(e);
> > }
> > };
> > }
> >
> > It's similar to Perl 'do BLOCK' expression
> > https://perldoc.perl.org/functions/do.html <
> https://perldoc.perl.org/functions/do.html>
> >
> > What do you think?
> >
> > With best regards,
> > Tagir Valeev
>
>
More information about the amber-spec-comments
mailing list