Live data from Hacker News

JEP draft: Prepare to make final mean final

openjdk.org

131–140 of 143 posts

Re: JEP draft: Prepare to make final mean final

#131
post #124

Earlier quoted context omitted.

> First, it's not a "crusade" but the steps necessary to deliver the features Java's users demand Semantics. Nobody demanded anything, if we want to play word games. The java philosophy of final, makes software less extensible. This is the point; to have less overriding. Regardless of what the voting body decides (the meaning of users being subtly repurposed), the feature is anti-developer-agency past the point of he…

Final making software less extensive is a red herring. The JEP is about final for fields, not final for classes. Nothing changes regarding the latter. It merely deprecates facilities that enable programmers to ignore the explicitly stated intentions of other developers.

> enable programmers to ignore the explicitly stated intentions of other developers

You say ignore. This is unnecessarily pejorative. You mean "change".

Software does not care about explicit intentions or who is leveraging it. Overriding is one of the essential methods of extending software.

Re: JEP draft: Prepare to make final mean final

#132
post #124

Earlier quoted context omitted.

Final making software less extensive is a red herring. The JEP is about final for fields, not final for classes. Nothing changes regarding the latter. It merely deprecates facilities that enable programmers to ignore the explicitly stated intentions of other developers.

> enable programmers to ignore the explicitly stated intentions of other developers You say ignore. This is unnecessarily pejorative. You mean "change". Software does not care about explicit intentions or who is leveraging it. Overriding is one of the essential methods of extending software.

Java allows you to freely change any decision made by any author of any library you use. None of that ability has been taken away.

However, changing other code (and potentially changing the assumptions on which it was built) shouldn't be as easy as using it in a way that preserves its assumptions. If it were just as easy, you could accidentally break other code's assumptions.

In some situations, all that's required of you is merely to declare that you indeed intend to change some other code's assumptions; in more involved situations (e.g. a library method computes the sum of its argument and you want to change it to compute the product) the work is more involved, but you can still do it relatively easily.

What we have blocked is the ability of a library to change the assumptions of another library or of the application's without the application knowing about it. A library absolutely must not be allowed to do that while hiding that from the application.

Re: JEP draft: Prepare to make final mean final

#133
post #116

Earlier quoted context omitted.

In Idea you have to explicitly select the fields which should be included. So it’s always choice of a developer to misuse it. My favorite question on interviews is explaining all methods of class Object, including the contract and best practices for equals/hashCode. Failure to answer this question automatically disqualifies applicants to mid-level and senior positions.

>all methods of class Object finalize() is actually is a very hard mode; I'd not expect any extra senior to be able to explain it properly (incl. the semantics of JMM, the fact half created objects can be finalized; the resurrection ability). Deprecated now, so perhaps no need? wait/notify/notifyAll - easier, still require some practice, also not that useful any longer; but still I'd expect to know not to use a naked…

> the standard templates for intellij could use some work when it comes to the quality of hashCode;

Doesn't everyone just use Objects::hash?

Re: JEP draft: Prepare to make final mean final

#134
post #133
post #116

Earlier quoted context omitted.

>all methods of class Object finalize() is actually is a very hard mode; I'd not expect any extra senior to be able to explain it properly (incl. the semantics of JMM, the fact half created objects can be finalized; the resurrection ability). Deprecated now, so perhaps no need? wait/notify/notifyAll - easier, still require some practice, also not that useful any longer; but still I'd expect to know not to use a naked…

> the standard templates for intellij could use some work when it comes to the quality of hashCode; Doesn't everyone just use Objects::hash?

>Doesn't everyone just use Objects::hash?

I hope they do know better, it's actually rather poor. 1st it should not be used for a single parameter - just use hashCode() directly and ensure non-null in the c-tor (or Objects.hashCode). Then, in general you need - only few fields to calc a decent high cardinality hashCode...

Last: 31 as a constant (used in most mul/add schemas by java). It's a single byte prime, so it has some benefits. It can be implemented via shift and add (x 32 and 30.

Re: JEP draft: Prepare to make final mean final

#135
post #126

Earlier quoted context omitted.

> Java doesn't even have a security model any more, so what are you protecting? That security model was obsolete and didn't fulfill its original purpose anymore. Most applications have never enabled it. > Programmers from their own mistakes? That's fine, but this is about cases where they set the "I really mean it and this isn't a mistake" flag. Not at all, the vast majority of code using this feature is part of libr…

> Do people really write `final` and are OK being aware that the field's value could still change after all? The converse: people really write `field.setAccessible(true)` and are OK being aware that they are breaking another programmer's assumptions. That's the point of `field.setAccessible(true)` existing at all. It's monkey-patching. Otherwise you might as well just delete the method and throw a `NoSuchMethodError`…

The excemptions outlined in the JEP still allow people to do pretty much whatever they want as granular as they want. They can even wholesale revert to the old behavior. I really don't see the issue.

> And, likewise, if the JVM never sees a write instruction to a certain field, except once in the constructor, it should be able to treat it as if the field were final, and avoid reloading it after method calls. If it loads a class with an instruction that writes that field, it has to recompile all those methods.

Right now, many opportunities for this optimization cannot be used because `final` for non-static fields cannot be relied upon. If such a field modification happens, then it's far more difficult to locate all the code that is the result of constant propagation from that field's original value. The impact of changes in the other scenarios is quite limited in comparison.

> None of this should be news to the JVM engineers.

I know how JIT compilers work, and the OpenJDK team knows as well of course. Which is exactly why they pursue this change. Deoptimizing and recompiling simply sucks for performance because this is time the application could spend on far better things.

Re: JEP draft: Prepare to make final mean final

#136
post #125
post #107

Earlier quoted context omitted.

>add them to hashCode and equals (or worse, hashCode OR equals) That's a fundamental misunderstanding of hashCode, and lombok makes no exception. Not all fields need to be used to calculate hashCode, it makes the overall performance worse in most cases. Equals is of course different, however if you have an identity (i.e. database primary key), only the identity should be used.

> That's a fundamental misunderstanding of hashCode Right. So the parenthetical clause should more correctly state "(or worse, adding them to hashCode but not equals)". That's fine, but it's still the same problem: there's a hidden dependency between changes in two or more locations. People make errors in those kind of updates all the time.

>or worse, adding them to hashCode but not equals

That's proper bad, however it should be noted in a pull request and explained how hashCode operates - people learn and improve.

> there's a hidden dependency between changes in two or more location

True, of course. However, just do not modify hashCode and consider if the extra fields do contribute to equality either.

Realistically I have not seen this error since very early 00s. I have seen use of mutable fields in hashCode, though (and the latter being modified while added to a hashset, used as map keys. lombok encourages such designs).

Another a lot more common error is "compareTo"

Re: JEP draft: Prepare to make final mean final

#137
post #128

Earlier quoted context omitted.

Const-ness in C++ is something I miss in other languages. Being immediate able to see that this function or method couldn't mutate the object made it so much easier to reason about the code. Yeah I know there's ways around it, but then the author known what they told the other party to expect.

D goes one step further, as const is transitive.

const is weird and I see no way of getting it right. Making const transitive in the way described in tha Dlang reference certainly sounds weird. It prevents totally valid use cases. Why wouldn't I have a const pointer to a mutable thing?

The real problem is that it's not defined what is an object, and where, in a web of memory-objects pointing to each other, a conceptual object begins and ends. It's arbitrary. Also, what is const from one standpoint is not const from another. It's fluid. Type systems generally don't play well with that. The weirdness of the original `strstr()` C API showcases that problem well.

The only thing that makes some sense here is to keep it simple -- any struct-like thing is an individual object. Embedded objects of course inherit const-ness, but pointed-to objects do not.

I think the C++ model is also somewhat right -- any class can define individually through which indirections const-ness follows through. But the C++ way causes lots and lots of boilerplate.

In any case, my solution is to use const very sparingly, it can hardly be gotten right in practice beyond basic use. Being more rigid of const may have prevents 2-3 bugs in my life, but cost sooo much more time and required many rewrites to make it fit somehow.

I use const mostly for

    - static const data
    - some string-slice datatypes (these are often initialized from static const data like string literals).
    - read-only function parameters passed by reference (Foo const *thing).

Re: JEP draft: Prepare to make final mean final

#138
post #135

Earlier quoted context omitted.

> Do people really write `final` and are OK being aware that the field's value could still change after all? The converse: people really write `field.setAccessible(true)` and are OK being aware that they are breaking another programmer's assumptions. That's the point of `field.setAccessible(true)` existing at all. It's monkey-patching. Otherwise you might as well just delete the method and throw a `NoSuchMethodError`…

The excemptions outlined in the JEP still allow people to do pretty much whatever they want as granular as they want. They can even wholesale revert to the old behavior. I really don't see the issue. > And, likewise, if the JVM never sees a write instruction to a certain field, except once in the constructor, it should be able to treat it as if the field were final, and avoid reloading it after method calls. If it lo…

Instance variables can't be constant propagated, can they? Different instances have different values.

Re: JEP draft: Prepare to make final mean final

#139
post #127

I don't see the point in putting another guard rail behind the override that's supposed to remove all guard rails. Java doesn't even have a security model any more, so what are you protecting? Programmers from their own mistakes? That's fine, but this is about cases where they set the "I really mean it and this isn't a mistake" flag. The JVM's optimized code from programmers? Plausible, but aren't there already many…

Yes it does, all of this is to make Java fully safe by default, in the age of cybersecurity laws, hence all loopholes are being closed down, in reflection, JNI and Panama. The security model was deprected, just like .NET dropped CAS in .NET Core, because it wasn't sound, and without applets, the OS security model was the right way.

If there's no security model then who are you protecting from who?

Re: JEP draft: Prepare to make final mean final

#140
post #128

Earlier quoted context omitted.

D goes one step further, as const is transitive.

const is weird and I see no way of getting it right. Making const transitive in the way described in tha Dlang reference certainly sounds weird. It prevents totally valid use cases. Why wouldn't I have a const pointer to a mutable thing? The real problem is that it's not defined what is an object, and where, in a web of memory-objects pointing to each other, a conceptual object begins and ends. It's arbitrary. Also,…

Hence why D has two approaches with similar semantics, const and immutable.

And also allows to alias non const references to the same data.

Thus the data can be modified by a mutable reference, owned by a specific part of the code, while everyone else only gets to see the const chain.

Post reply on HN