Live data from Hacker News

JEP draft: Prepare to make final mean final

openjdk.org

11–20 of 143 posts

Re: JEP draft: Prepare to make final mean final

#11

Great! Now can we make `final` the default for all fields, variables, and parameters? (yes yes, I know, that would break syntax... but please come up with something to discourage mutability)

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.

Yeah I find it a bit startling going from rust (where const is the default) to basically any other language. Sometimes I look at typescript function definitions and I’m like - uuuuhhh does this function mutate that parameter? Does it keep a reference to it? If the object I’m passing is mutated after I call this function, will something break? It’s impossible to tell from a function signature, even with all of typescript’s type safety. That gives me the willies. - and for good reason, it’s tripped me up lots of times.

Even the JS standard library struggles with this. You just have to remember that .sort() modifies the array in place (and returns it), but .slice() does a shallow clone of the array. (Not a deep clone - that would be different again!)

Re: JEP draft: Prepare to make final mean final

#12
post #6

A cursory glance at "setAccessible" usage reveals popular libraries such as serializers like gson and jaxb, class manipulation and generation like cglib, aspectj and even jdk.internal.reflect, testing frameworks and libraries including junit, mockito and other mocking libraries, lombok, groovy, spring, and the list goes on and on. My bet is that this will be yet another "checked exception" or "module system", where m…

setAccessible is also used to be able to access private fields, and not just to be able to write to final fields. Most libraries shouldn't need to set final fields, and I say this as someone who was very against when they deprecated java.lang.misc.Unsafe. I've only had to set a final field once in my career and it was related to some obscure MySql/JDBC driver bug/workaround. This particular deprecation seems very sensible to me.

Re: JEP draft: Prepare to make final mean final

#13
post #6

A cursory glance at "setAccessible" usage reveals popular libraries such as serializers like gson and jaxb, class manipulation and generation like cglib, aspectj and even jdk.internal.reflect, testing frameworks and libraries including junit, mockito and other mocking libraries, lombok, groovy, spring, and the list goes on and on. My bet is that this will be yet another "checked exception" or "module system", where m…

Yeah like the module system. Looks good on paper, is probably hard to deal with. There are still tons of popular libraries that have no module-info. Java does evolve, but the direction it does is so weird. And than the tooling is strange and it’s worse that there are basically two build tools, both with their upsides and downsides but they still feel more complicated than tools for other languages like cargo, go (if you consider that), msbuild (the modern csproj stuff/slnx)

Re: JEP draft: Prepare to make final mean final

#15

I would like to see some realistic example scenarios where this could actually lead to a speedup and how much it actually speeds up.

The article mentions one: const folding. I don't think we need a benchmark to suggest that could mean a performance improvement in some cases.

Regardless, to me this isn't about performance, this is about "integrity" (to use the same term as in the JEP): consumers of my library should not be mucking about in private implementation details, and then inevitably complaining about problems to me when something breaks. If you need a feature that I don't expose, ask for it (or better yet, submit a patch).

Sure, I've used reflection to modify library internals before, but I recognize that whenever I do that I'm inviting a maintenance headache into my world. But some people just think things should always work, even when they are breaking them.

Re: JEP draft: Prepare to make final mean final

#16
post #6

A cursory glance at "setAccessible" usage reveals popular libraries such as serializers like gson and jaxb, class manipulation and generation like cglib, aspectj and even jdk.internal.reflect, testing frameworks and libraries including junit, mockito and other mocking libraries, lombok, groovy, spring, and the list goes on and on. My bet is that this will be yet another "checked exception" or "module system", where m…

setAccessible is also used to be able to access private fields, and not just to be able to write to final fields. Most libraries shouldn't need to set final fields, and I say this as someone who was very against when they deprecated java.lang.misc.Unsafe. I've only had to set a final field once in my career and it was related to some obscure MySql/JDBC driver bug/workaround. This particular deprecation seems very sen…

So how should GSON initialize an object?

The theory is, go through the constructor. However, some objects are designed to go through several steps before reaching the desired state.

If GSON must deserialize {…, state:”CONFIRMED”}, it needs to call new Transaction(account1, account2, amount), then .setState(STARTED) then .setState(PENDING) then .setState(PAID) then .setState(CONFIRMED) ? That’s the theory of the constructor and mutation methods guarding the state, so that it is physically impossible to reach a wrong state.

There is a convention that deserialization is an exception to this theory: It should be able to restore the object as-is, after for example a transfer over the wire. So it was conventionally enabled to set final variables of the object, but only at initialization and only for its own good. It was assumed that, even though GSON could reach a state that was unachievable through normal means, it was, after all, the role of the programmer to add the right annotations to avoid this.

So how do we do it now?

Re: JEP draft: Prepare to make final mean final

#17
post #4

From my perspective as a C++ developer, every attempt to use `const` for compiler optimization appears to be stymied by the existence of `const_cast`, because modifying a `const` value is only undefined behaviour if the underlying object is `const`. Glad to see that Java is willing to break the language to improve it.

> modifying a `const` value is only undefined behaviour if the underlying object is `const`.

I found this sentence confusing. You mean that modifying a value that has been const_cast is undefined behaviour only if the original variable was const right? Or something else?

Re: JEP draft: Prepare to make final mean final

#18
post #11

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.

Yeah I find it a bit startling going from rust (where const is the default) to basically any other language. Sometimes I look at typescript function definitions and I’m like - uuuuhhh does this function mutate that parameter? Does it keep a reference to it? If the object I’m passing is mutated after I call this function, will something break? It’s impossible to tell from a function signature, even with all of typescr…

> Even the JS standard library struggles with this. You just have to remember that .sort() modifies the array in place

ISTM that there are almost always some kinds of mutable data structures present in non-trivial programs. And outside of the program, you have databases to directories of files that get mutated by users or other parts of a program. I think this is just a fact of life.

Re: JEP draft: Prepare to make final mean final

#19

Earlier quoted context omitted.

setAccessible is also used to be able to access private fields, and not just to be able to write to final fields. Most libraries shouldn't need to set final fields, and I say this as someone who was very against when they deprecated java.lang.misc.Unsafe. I've only had to set a final field once in my career and it was related to some obscure MySql/JDBC driver bug/workaround. This particular deprecation seems very sen…

So how should GSON initialize an object? The theory is, go through the constructor. However, some objects are designed to go through several steps before reaching the desired state. If GSON must deserialize {…, state:”CONFIRMED”}, it needs to call new Transaction(account1, account2, amount), then .setState(STARTED) then .setState(PENDING) then .setState(PAID) then .setState(CONFIRMED) ? That’s the theory of the const…

Why would you use GSON for objects that go through steps of state? Why would you mark fields like State as final when it is actually mutable? This just sounds like poorly designed code.

Maybe I don't know of your use case, but GSON/Jackson/Json type classes are strictly data that should only represent the data coming over the wire. If you need to further manipulate that data it sounds like the classes have too much responsibility.

Re: JEP draft: Prepare to make final mean final

#20
post #11

Earlier quoted context omitted.

Yeah I find it a bit startling going from rust (where const is the default) to basically any other language. Sometimes I look at typescript function definitions and I’m like - uuuuhhh does this function mutate that parameter? Does it keep a reference to it? If the object I’m passing is mutated after I call this function, will something break? It’s impossible to tell from a function signature, even with all of typescr…

> Even the JS standard library struggles with this. You just have to remember that .sort() modifies the array in place ISTM that there are almost always some kinds of mutable data structures present in non-trivial programs. And outside of the program, you have databases to directories of files that get mutated by users or other parts of a program. I think this is just a fact of life.

The point isn't that there's mutability, it's to be able to easily identify where it is and where it is not.

Languages which lack the tools to do this are just harder to reason about, at least for me.

In the JS example, as a non-JS coder, I would expect that a sort function that returns nothing/void would sort in-place, while a sort function that returns an array would return a sorted copy. I would not expect it to sort in-place and return it.

However in C++ I could easily see from the function definition that it might be doing that, because a sort that returns a copy would take a const reference for the input array. So if I came across a sort function which took a non-const reference as input I'd be able to at least suspect it's doing it in-place.

Post reply on HN