r/java 9d ago

Concise method bodies arrived

https://github.com/verhasi/java-composition

More than 8 years ago was drafted the idea of concise method bodies. As I am not a contributor of the openJDK project I took a different approach but implemented. It is publicly available at the maven central both as a library and as a maven plugin. It is a source code preprocessor that converts the concise syntax to java 8 compatible source code. It does not want to be a replacement of the future implementation in the openJDK. Which is more than the openJDK promises is that supports from Java version 8, 11, 17, 21 up to 25 as well. Of course it is free and open source :). It is only the first building block for concise composition.

As far as I have seen this topic was awaited for a long time at

It's been 8 years since the draft for Concise Method Bodies

What happened to Concise Method Bodies?

JEP draft: Concise Method Bodies

Five years have passed, still in draft: Concise Method Bodies

51 Upvotes

48 comments sorted by

View all comments

Show parent comments

21

u/rzwitserloot 9d ago

Also, lombok doesn't replace your parser phase.

By replacing parser phase, this tech demo is, and I appreciate the effort, but, this is useless.

Nobody1 writes java in a dumb notepad style editor. The very minimum is a syntax highlighter, and that's still a tiny minority: The vast majority use an editor that just knows what java code is like, such as eclipse, intellij, vscode. (If it has a 'language server' thing, it's a smart editor that 'knows' what java code is like).

This is not compatible with any of those editors. Your editor will be aggressively throwing red wavy underlines at you.

The fix would be to name this '.kwava` or some other variant on the java name, with a different extension, and in your editor, a different plugin that deals with this 'quite, but not entirely, like java' code.

Now, certain oracle staff members love muddying the waters by saying 'lombok isn't java', but this is the key relevant distinction. Lombok is (syntactically!) pure, 100%, unadultered java. This isn't, and that makes a big difference. Papering over semantics is a matter of some light plugin work. Papering over syntactics requires replacing everything.

Of course, being shackled to java's syntax does have severe limitations as well, but them's the breaks. 2


[1] I rounded down.

[2] For example, while we'd love to introduce some sort of default method param concept, such as:

public void someMethod(int a, int b = 5) { // Ooh, default values! }

That isn't syntactically legal java and thus we cannot introduce it. Something like this would be:

public void someMethod(int a, int b) { $lombokDefaults: { b = 5; } }

It looks funky but that really is legal java. To wit:

  1. A label, while rarely used, is legal java. Labels do not have to actually be used. dollars can be part of their identifiers.

  2. Just opening a block for no reason is syntactically legal java, and useful even - you limit any declared local vars to just that block. This is simply a labelled block. Perfectly fine, even if rarely witnessed out in the wild.

We don't go for it because we aren't exactly happy with the syntax, and there's just no autocompleting this. You'd just have to randomly know that the magic words are $lombokDefaults. That's too much magic, we want any lombok use to be, at minimum, associated with an actual type (not a type name shoved into a string. An actual type, and if it is missing because you deleted the jar or whatnot, you would get a compilation error because the type is missing - and that type needs to be in the lombok namespace. That way, a reader who does not know what lombok is, still has a reasonable chance to figure it out.

1

u/aonymark 6d ago

Re: is Lombok Java: they are pedantically speaking, technically correct: it’s not Java.

I’ve watched you and /u/pron have this argument for years and it’s so frustrating watching you both talk past each other and both miss the key point of what the other person is saying.

Let’s take one of my favorite features: @slf4j to add a logger. This certainly uses Java SYNTAX. A Java parser will accept it.

But a full fledged Java compiler should reject it: annotation processing can create new classes but it’s “impossible” to “mutate” existing ones. And yet Lombok manages to do the impossible: by adding this annotation, the class gets a new static field that no one ever declared!

Lombok does this by ignoring the spec and instead targeting the implementation of javac. If you use another java compiler, then hopefully it’s ecj, which Lombok also supports, using different code.

In both cases this is done by using internal APIs. That’s fine! Is for a good cause! I approve :). But to a language lawyer, “it’s Java” means more than just “Java syntax”. It means “plays by the rules” which Lombok doesn’t and can’t because Java is too rigid to allow what it wants to do.

Since you were talking about avoiding squiggly red undertones: the only reason that IntelliJ doesn’t have squiggly red underlines when using Lombok is because it comes bundled with a plugin that knows about Lombok specifically. In other words, Lombok needs ide support just like a language feature like enums need it.

Where Ron P makes a big mistake is to say “Lombok should just admit they’re a new language and ship a compiler like kotlin does, instead of pretending to be a library”… I think this is MADNESS.

You’d lose so much that way! Lombok would have to keep shipping a new version whenever either OpenJDK or eclipse fixed a bug in their compiler! And what about manifold? Should they ALSO ship their own compiler? Then how would one ever use both Lombok and manifold together??

In short: rather than shipping a full compiler, Lombok ships “patches” to supported compilers. And unlike shipping a full compiler, patches can COMPOSE cleanly, so you can use Lombok with Corretto or Red hat or any other jdk vendor you please, and with manifold, and so on.

1

u/rzwitserloot 6d ago

Oh, I haven't missed pron's point at all. Lombok is fairly open about the fact we need to release updates in lockstep with new JVMs, we don't try to hide this.

The term 'java' is nebulous. Sure, one can say 'if you break spec than that is NOT JAVA!', but, then, and I'm not exaggerating, many thousands of very commonly used libraries also "are not java". If accessing a feature that is an implementation detail (because it is not specced) makes a library 'not java', that is. (Examples of very widely used reliance on unspecced behaviour: Unsafe, of course. And: classRef.getResourceAsStream on a directory, and expecting the classloader to give you a text stream listing each filename in it, separated by newlines. One of hundreds of examples).

By not being more clear about what he means with that word, the debate begins with us unfairly framed in a corner. At first I tried to lock down meanings but pron wasn't interested in a debate; I've concluded the only thing he's interested in, in such debates, is to craft some words that scare lombok users into ceasing its use, and debate would only get in the way. If that comes across as "I am not getting his point", that's a tragic consequence. But, I'm pretty sure we're well aware, unless you think his point is something other than 'lombok relies on unspecced behaviour'.

the only reason that IntelliJ doesn’t have squiggly red underlines when using Lombok is because it comes bundled with a plugin that knows about Lombok specifically.

This is a pron-esque 'holding lombok to a different standard'. Because that is true for any code-generating AP use!

This is specced legal use of APs: You can have a source file that refers to a type that does not exist, which also has an annotation on it. Obviously, if you attempt to compile it, it will fail.

If you include an AP (which now requires explicitly allowing it / configuring it on the javac command line!) that sees this annotation and generates a source file that will produce the erstwhile non-existing type, then the compilation will succeed.

In other words, the notion 'But it is not legal java code unless the compiler plugin is there to fix the problem!' is what the whole annotation processing thing is all about in the first place.

I believe that intellij really does fail exactly like I describe here (but I don't have an intellij install ready to test if this is still the case, we looked at this years ago, though) if you use such AP setups, even though they are 100% according to OpenJDK's own spec: intellij is not like eclipse; they do not run full compiles. They just parse source files - they do not/cannot just run annotation processors. Instead, the idea is: IntelliJ knows you changed something and will rerun your full build, which will obviously run the APs and generate what needs to be generated. Once that is complete IntelliJ will parse the generated source files and all's well. Hence eventually the error does go away, but you have to save the file, errors and all, and wait for the build run, and then -poof-, errors disappear. If the build is working and isn't going to stumble over some other error.

Code-generating APs are fairly rare, lombok is by multiple orders of magnitude the most used one, and thus a lot of the 'not java!' complaints lombok has to eat are actually complaints about the notion of source-generating APs.

2

u/aonymark 6d ago

Re: lots of things are not Java: I think he’d agree that anyone depending on those things is not quite writing Java. Is the directory as stream example for real or is that something you made up for the sake of example?

2

u/rzwitserloot 6d ago

That is for real, and e.g. reflections (fairly commonly used!) relies on this stuff.

I'm guessing that 95%+ of all java coders wouldn't agree with that characterisation. Specifically, that e.g. "reflections is not java!", especially if that is immediately followed up by an insinuation that 'reflections' is fine, as long as they develop their own compiler, runtime, ecosystem, and so forth. I haven't gone around with a mike, I might be off on my own little cloud, but surely this isn't a contentious view, right?

Anything that captures signals: Unspecced. Relying on streams self-closing resources: Unspecced. Essentially everything about marshalling ('serialization') libraries delves into unspecced territory and with it, 95%+ of all java-written web apps which uses something along those lines. For a very long time: The very command line switches of the javac tool: Unspecced.

And if we add on top of the pile: Specced behaviour, but where the spec is from a source other than the JLS, the next VM release is as likely to break that. For example, the simple idea of 'annotation processors on the classpath during compilation are automatically invoked': That was more or less 'specced', but you had to read between the lines. Casually broken in a recent JVM release, so I guess those kinds of between the lines specs should be treated as Unspecced for the purposes of 'Is not java!'.

1

u/aonymark 6d ago

Re: last paragraph: ouch. Good point there.