So, to close the loop here ...
Based on these comments, we went through three more rounds of API
design, and ... ended up in a pretty similar place to where we started.
First we tried a more formal separation between "Constable" and
"ConstantPoolEntry." Then we tried a CP-entry-centric approach. And
what that brought us back to was, that the central abstraction here is
the symbolic references -- that this isn't only about intrinsification.
(If it were, then the comments regarding macro-systems would be
spot-on.) So the current draft brings the symbolic references front and
center -- and leaves intrinsification and constant pool entries
deliberately in the background.
On 9/2/2017 10:51 AM, Remi Forax wrote:
Brian ask me to explain my concerns about the Constable interface.
The whole constant folding story is like a macro system, it's a limited macro
system, but still a macro system.
I've developed several macro systems, all have limitations, some limitation
that i have introduced voluntarily, some that have appear after being being
used, all the macro systems have always evolved after the first release.
So the first lesson of designing a macro system seems to be, because it will
evolve, it should provide the minimal API so it can be refactored easily.
In the case of constant-folding mechanism, it's not a mechanism that target end
users but JDK maintainers, so end users should not be able to see the
implementation of such mecanism.
It's my main concern with the Constable interface, it's a public visible type
with a public visible API.
We have already introduced in the past a mechanism that requires a specific
interaction between the user code, the JDK and the compiler, it's the
polymorphic methods signature and it was solved by using a private annotation.
I think constant folding should use the same trick. Mark constant foldable type
with a hidden annotation (@Constable ?) and mark methods (private) that can be
called by the compiler with another hidden annotation (@TrackableConstant ?)
and i will be happy.
Compared to using an interface, there is a loss of discover-ability from the
end user, but their is no loss of compiler checking because the compiler can
check if a type is annotated by an annotation the same way it can check if it
implements an interface.
Now, we can discuss if @Constable should be a public annotation or not because
once a type can be constant folded, removing the annotation is a non backward
compatible change. So having the @Constable public is perhaps better than
having to have a sentence in the middle of the javadoc saying that this is a
constant foladable type.
Note that constant folding things is also a form of serialization, the first
Java serialization API have made that mistake to make the implementation of the
part that serialize each object too visible. I think we can do better here.
You can also think that like Serializable, Constable could be an empty
interface and ldc will take a Constable. But int constant-foldable and i do not
see why it should be boxed to an Integer to becomes Constable (The full
implication of that is that ldc should be a method with a polymorphic signature
but we are moving in that direction anyway).
Long live to @Constable !
regards,
Rémi