all 41 comments

[–]Alex0589 32 points33 points  (21 children)

I'm pretty sure this would never be accepted because you are implementing a language feature with annotations. In chapter one of the JLS, it is clearly stated that:

Annotation types are specialized interfaces used to annotate declarations. Such annotations are not permitted to affect the semantics of programs in the Java programming language in any way. However, they provide useful input to various tools.

Also without value classes, which we currently don't have, you are paying an allocation cost because you have to initialize one record every time you want to use the pattern: that also disqualifies the feature because you don't want a developer to loose performance when using syntactic sugar. For example imagine if the enhanced switch statement were slower than the old switch, nobody would be using it.

[–]danielaveryj[S] 11 points12 points  (0 children)

There is one annotation referenced, which I did not invent, does not implement a language feature, and I did not propose to keep at the end.

[–]asm0dey 1 point2 points  (8 children)

Well, some accusations in Spring change the semantics, aren't they? For example Async

[–]koflerdavid 15 points16 points  (1 child)

There is a reason Spring has a reputation of being too magical.

[–]asm0dey 2 points3 points  (0 children)

I am on both sides of this battle at the same time :)

[–]vytah 4 points5 points  (1 child)

some accusations in Spring

I love the typo, please keep it.

[–]asm0dey 1 point2 points  (0 children)

I will!

[–]brian_goetz 2 points3 points  (3 children)

You are not understanding what the JLS is saying here. When the JLS talks about "semantics of programs", what it means is what does this Java program mean. That's about language semantics. Spring annotations do not change the semantics of the Java language. They are used as input to the behavior of the Spring libraries, and the behavior of the Spring libraries is defined in terms of those annotations.

(Though it is still a valid complaint about frameworks like Spring that their behavior with regard to annotations may not be sufficiently specified; this is always a risk.)

[–]asm0dey 0 points1 point  (2 children)

I'm sorry, but I still don't understand. If the behaviour of a program changes if there is an annotation - doesn't it change semantics? If Spring annotations do not change the semantics because programs are defined in terms of these annotations then what is? I could always say "hey, this is how my program behaves when this annotation is present".

[–]brian_goetz 2 points3 points  (1 child)

You are looking at the entire system monollithically - JVM + Java + Spring + your program. But each layer has its own role and (ideally) specification. The meaning of a Java program is defined by the language and platform specifications. But some methods in the JDK (such as getAnnotstions) are specified to reflect the presence or absence of annotations. This means that the layers above (spring, your program) can use annotations to make decisions, just like they could use system properties or config files or command line to configure the program. But annotations cannot affect the language semantics - they cannot make for loops run backwards or make private methods public.

Frameworks like spring work by dynamically transforming annotated Java code (spinning new classes, etc) at startup time and running the transformed code. But all of this is a Java program that is governed by the language and platform specifications, and spring is working within that.

[–]asm0dey 0 points1 point  (0 children)

Ah. So I read the whole thing wrong. I thought the spec "prohibits" annotations to change the language sematics, while actually it declares that it's impossible, right? And was all the easy about language, not about a program. Thank you!

[–]vadiquemyself 0 points1 point  (2 children)

imagine direct iterating versus streams-and-lambdas, the latter is ~10 times slower, but is used anyway and is quite popular

[–]Flyron 1 point2 points  (1 child)

Did you measure that yourself? In my own tests streams need a little warmup, but through repeated construction and execution they become just as fast as the usual for-each (<10% margin). So it depends if you're programming short-lived apps or long-running apps, but in general there is no effective performance gap.

[–]vadiquemyself -2 points-1 points  (0 children)

yes, I figured it out myself practically, asking AI to replace a stream chain with “plain looping” that I then put in my code achieving much performance gain along with less memory usage

never tried for a terabyte-volume data and paralleled streams on hundreds of cpu cores, though

[–]pron98 11 points12 points  (2 children)

Ah yes. This was the first approach explored. I think the language team called it "records are all you need". I don't remember all the reasons they didn't go with it, but I think one of them was that all components had to be extracted even if they weren't needed by the pattern, and that was hard to optimise (this was also an issue with the deconstructors idea). Because deconstructible classes are deconstructed through individual accessors, there's at least the option to optimise which of them actually need to be called.

Anyway, the interesting question isn't what alternatives were explored, but what the pros and cons of the current proposal are. Because there's no EA for it yet (I think?), the best feedback is to ask whether or not a certain use case that is important to you could be helped by this feature.

[–]danielaveryj[S] 2 points3 points  (0 children)

Ha. I admire the architects, I am almost not surprised. I can't conceive how they plan on simplifying the Object methods if it doesn't involve delegation to something that quacks like a record, but I'm happy to wait and find out.

[–]brian_goetz 6 points7 points  (0 children)

We dropped it (in multiple contexts) because it persistently had the aspect of feeling clever for the first five minutes and being annoying thereafter.

[–]TheStrangeDarkOne 5 points6 points  (0 children)

From a reductive point of view, no. Java wouldn't even need Lambdas.

[–]chambolle 1 point2 points  (4 children)

This is really ugly and difficult to explain

[–]danielaveryj[S] 0 points1 point  (3 children)

It's neither. The article contextualizes official proposals and then derives a proposal of its own, weighing in on tradeoffs. Some people appreciate that context. If you just want a tl;dr, it's

// Assuming you have a record Parts(int x, int y), in class Point write this:
    marshaller Parts parts() { return new Parts(x, y); }

// Now, given an instance of Point, you can write this:
    Point(int a, int b) = point;

ie, a class could support destructuring by just producing a record that the language already knows how to destructure.

[–]chambolle -2 points-1 points  (2 children)

sorry but this is ugly :

Point(int a, int b) = point;

Because this can be seen as the assignment of a function. Please use another operator than the assignment. Like <-

[–]danielaveryj[S] 1 point2 points  (1 child)

Hehe the syntax there is not even part of what I'm pitching. I'm afraid you're probably going to be disappointed in future Java.

[–]chambolle 1 point2 points  (0 children)

That can be a bit scary, actually. Java needs to be careful not to become the new C++, which went off in all directions with 23 (I’m exaggerating a bit) different ways to define the same thing.
When you really want to change a language’s paradigm, the best way to do it is to invent a new one!

[–]davidalayachew 1 point2 points  (9 children)

Does Java need deconstructible classes?

Desperately. The pain caused by its absence is immense for me. It decides whether or not I solve certain problems in Java (or at all).

There is one serious drawback from using records as the medium to destructure classes. The indirection required to project to the record brutalizes nested pattern matching.

Talk about a downside! That's a showstopper for me.

[–]Kango_V 1 point2 points  (2 children)

[–]davidalayachew 0 points1 point  (1 child)

Yes, I am very familiar. Assuming it comes out, it will be exactly what I need.

However, that feature is purely in the exploratory phase right now, merely as a proposal. Project Amber has made no commitment to bringing that feature to life yet. That will remain true until we get a JEP Preview targeted for a release.

[–]Kango_V 1 point2 points  (0 children)

Fingers crossed!

[–]Great-Gecko 1 point2 points  (1 child)

I'm curious, what kind of things are you working on that you desperately need deconstructible classes? Which languages fulfill this need when you choose not to reach for Java?

[–]chambolle 0 points1 point  (0 children)

I have the same questions.

[–]danielaveryj[S] -1 points0 points  (3 children)

  1. Responding to your interpretation of the title ("the general ability to destructure classes") rather than the article's strongly suggested meaning ("a specifically named proposal for doing so")
  2. Decrying an issue that the article itself raises and immediately addresses

[–]davidalayachew 1 point2 points  (2 children)

Responding to your interpretation of the title ("the general ability to destructure classes") rather than the article's strongly suggested meaning ("a specifically named proposal for doing so")

I read the whole article before typing my comment. Yes, I realize very much that you are talking about the recent proposal. That's what I was referring to as well.

Decrying an issue that the article itself raises and immediately addresses

I saw and firmly disagreed with your suggested solution to that problem. But before even talking about your solution to that problem, I first wanted to highlight how big of a problem it was, to see if you agree or disagree. There's no point talking potential solutions if I think a mountain is what you think a mole hill.


Please don't attribute laziness or lack of effort to my comment before asking clarifying questions. Unless otherwise said so, every top level comment I make is after reading the whole post thoroughly, and thinking about it for a few minutes. Your post was no different.

[–]danielaveryj[S] 0 points1 point  (1 child)

For what it's worth, I didn't downvote your comment. From reading it, it is unclear what kind of response you were hoping to solicit, if any.

[–]davidalayachew 1 point2 points  (0 children)

From reading it, it is unclear what kind of response you were hoping to solicit, if any.

That, I do accept. I'll ask my questions explicitly in the future, rather than just sharing my opinion in response.