No, that's a mistake in the article. The variable is still captured by reference, but `let` is causing it to be re-declared on every iteration of the loop, not mutated.
The following code prints 1, 2, 3. It wouldn't do that if the variable was captured by value.
for (let i = 0; i < 3;) {
setTimeout(() => console.log(i));
i++;
}
The behavior of "let" with for loops where the variable is declared more times than it is initialized, despite the source code having one declaration that is also the only initialization, is not very explicit.
for (let i=0;i<3;i++) {
i+=10;
setTimeout(_=>console.log(i),30);
i-=10
}
Capture by value would print 10, 11, 12 that's the value when it was captured
Capture by reference would print 0,1,2
It's much easier to conceptualise it as
for (const i=0;i<3;i++) {
setTimeout(_=>console.log(i),30);
}
which is fine because i never changes. It is a different i each time.
fancier example
for (let x = 0, y = 0; y < 2; x=x++<3?x:y++,0){
x+=10;
y+=10;
console.log("inline:",x,y);
setTimeout(_=>console.log("timeout",x,y),30);
x-=10;
y-=10;
}
Parroting something i have heard at a Java conference several years ago, tail recursion remove stack frames but the security model is based on stack frames, so it has to be a JVM optimization, not a compiler optimization.
I've no idea if this fact still holds when the security manager will be removed.
The security manager was removed (well, “permanently disabled”) in Java 24. As you note, the permissions available at any given point can depend on the permissions of the code on the stack, and TCO affects this. Removal of the SM thus removes one impediment to TCO.
However, there are other things still in the platform for which stack frames are significant. These are referred to as “caller sensitive” methods. An example is Class.forName(). This looks up the given name in the classloader of the class that contains the calling code. If the stack frames were shifted around by TCO, this might cause Class.forName() to use the wrong classloader.
No doubt there are ways to overcome this — the JVM does inlining after all — but there’s work to be done and problems to be solved.
There are similarities in the problems, but there are also fundamental differences. With inlining, the JVM can always decide to deoptimize and back out the inlining without affecting the correctness of the result. But it can't do that with tail calls without exposting the program to a risk of StackOverflowError.
We've been using TCO here ("tail call optimization") but I recall Guy Steele advocating for calling this feature TCE ("elimination") because programs can rely on TCE for correctness.
I'm sympathetic to the points being made but the argument that Oracle does not have its own JavaScript runtime does not hold.
An OracleBD is able to execute triggers written in JavaScript since quite some time.
I don't think the article outright claims Oracle has no JavaScript runtime, only that Oracle JET is no runtime, which is true. And since this is the evidence Oracle presented to keep the trademark, it's fair to point out that this is nonsense. But it's also true that if this goes to court, Oracle could present GraalJS (which is used in OracleDB) as evidence for their case.
Is their a design document, somewhere about this new library ?
The jep does not explain how to prepare to new Java bytecodes and future enhancements. Am i suppose to only run with the latest version of Java if i want to use that library ?
Very true, in Java, at least in the last 20 years, inheritance is de-facto deprecated, all new bits and bolts like enums, annotations, lambdas or records do not support inheritance.
Several years ago I briefly worked at a major telecommunications provider with services across the southern United States that ran Python 2.4 on their production provisioning servers. Worked just fine.
This is similar to the expression tree API of C# so no change in the JVM is required, only cooperation between the java compiler and the reflection API.
The code model can be computed by the compiler, inserted in the classfile in a specific binary or text format and read at runtime using the reflection API.
I've not taken a look to the implementation so it's speculation but I do not think the JVM need to be changed.
I think it's fair to call that semantics "implicit".