This proposal is trying to implement lazy evaluation without adding any new syntax. Your version would require a change to the parser, where this is just a new standard class.
A commenter above points out that there's a competing proposal that does introduce new syntax in the form of a `lazy` keyword:
The architects are wary about introducing new syntax into the Language. If it can be accomplished with an API, it should be done that way. Also, this keyword would probably use something like ComputedConstants in the background, and doing it this way would sweep that under the rug, which is also generally not how most Java features work. The delayed nature of this initialization is also not explicitly highlighted (unlike the lambda we would have to use with ComputedConstants), which will eventually bite people.
please for the love of gosling give us reasonable data structure literals nobody cares about this stuff i just want to be able to create a map or list w/o ceremony please
Perhaps you are using the wrong language. You should probably just stick with python or javascript where they just have simple lists and maps and pretty much nothing else.
A Java programmer feeling superior? Who would have though the day will come.
In all seriousness, this is grade school BS.
(a) Literals are a syntax improvement. Much more serious languages than Java have them.
(b) What Python and JS have don't amount to "simple lists and maps". They have the full gamut (including constructor based instantiation of different types).
(c) Literals don't have to be a single ("simple" or not) type. They can be whatever, and in Java these could include different classes of lists and maps initialized with the same literal syntax based on the assigned variable's type.
(d) When Oracle gives literals, Java programmers not familiar with them in other languages will suddenly love them too, and they'd not just be "for Python and Javascript" anymore.
It's that, plus caching. It's basically what a thunk is called in Haskell land. You could also describe it as a Future, but with a vastly simplified API (no exceptions to catch when calling `get()`) thanks to being intended for the single-threaded case.
As far as I understood this is very much intended to be used in multi-threaded code as well. If you are sure that your object won't be called in multiple threads you can just do the simple "if(ref == null)" without locking and it should be reasonably fast - just not constant-foldable by the JVM.
The ComputedConstant indeed has to be threadsafe, but the proposal reads as its initializer would be executed on the thread of the caller of get(), and other callers would have to wait until initialization has completed. Indeed very useful for multithreaded programs as well.
There were another JEP draft [1] recently that was proposing to introduce a lazy keyword for static fields. This new JEP looks like an alternative without any language change, and seems more likely to prevail.
Not quite. You need to have control over the JVM to do what this class does. The whole point of this class is a lazy value that interacts with the JIT in desirable ways.
Sure, but that's an (important) implementation detail. If this JEP is merged both Scala and Kotlin could implement their respective features in terms of ComputedConstant and get the performance enhancements for free.
Meaning it's semantically the same, with non-functional benefits.
A ton of comments are missing the point of this complaining about list/map syntax etc. I'm not sure if the kotlin lazy addresses this.
The point is that static final variables interact especially well with the JIT's constant folding machinery. But lazy loading a constant necessitates that it can't be final: it's initially null until it's effectively final after the first lazy load. This finality is clear to the developer but not to the JVM.
This is introduces a way to implement lazy constants via a blessed class that solves this.
The article is pretty clear about what the point is — but does require some careful reading and context.
The example used is the venerable Logger class from the log4j package. It seem implausible that imprecise constant folding would cause a measurable performance decrease when using that class. So to me the point is not clear. A more convincing argument would be before and after stats of a benchmark showing x% performance increase.
It is not necessarily lazy. Computations might, for example, be time-shifted to link time instead of runtime. See some of the notes on project Leyden for more details [1].
This reminds me of 'sync.Once' from the Golang. Very nice to have this sort of functionality in the stdlib. Glad to see Java getting something similar.
37 comments
[ 2.4 ms ] story [ 82.9 ms ] threadA commenter above points out that there's a competing proposal that does introduce new syntax in the form of a `lazy` keyword:
https://news.ycombinator.com/item?id=36993023
In all seriousness, this is grade school BS.
(a) Literals are a syntax improvement. Much more serious languages than Java have them.
(b) What Python and JS have don't amount to "simple lists and maps". They have the full gamut (including constructor based instantiation of different types).
(c) Literals don't have to be a single ("simple" or not) type. They can be whatever, and in Java these could include different classes of lists and maps initialized with the same literal syntax based on the assigned variable's type.
(d) When Oracle gives literals, Java programmers not familiar with them in other languages will suddenly love them too, and they'd not just be "for Python and Javascript" anymore.
[0] https://kotlinlang.org/docs/delegated-properties.html#lazy-p...
[1] https://www.baeldung.com/scala/lazy-val
[1] JEP draft: Lazy Static Final Fields - https://openjdk.org/jeps/8209964
Meaning it's semantically the same, with non-functional benefits.
Cons: extremely painful amounts of churn for everyone
The point is that static final variables interact especially well with the JIT's constant folding machinery. But lazy loading a constant necessitates that it can't be final: it's initially null until it's effectively final after the first lazy load. This finality is clear to the developer but not to the JVM.
This is introduces a way to implement lazy constants via a blessed class that solves this.
The article is pretty clear about what the point is — but does require some careful reading and context.
https://github.com/spullara/java-future-jdk8/blob/master/src...
https://openjdk.org/projects/leyden/notes/02-shift-and-const...
But for the love of Glob I wish web page authors would cease their contrast brinkmanship. Most of the text is barely discernible from the background.
[1] https://en.wikipedia.org/wiki/Initialization-on-demand_holde...
Any class doing IO is a dependency, so you normally would just inject it via the constructor of the class.