Project Leyden: Beginnings
John Rose
john.r.rose at oracle.com
Tue May 24 18:30:32 UTC 2022
On 23 May 2022, at 9:10, Ioi Lam wrote:
(more)
> …
> One parallel to draw from is the "constexpr" keyword in C++.
Please take a look also at the ideas in D around pure and immutable
computations. They allow time-shifting of very complicated D programs
to compile time. I saw a demo (long ago) of compile-time data weaving
in D which took an immutable bundle of strings, transformed them and ran
the result as D expressions through the D compiler itself (as a subtask,
at compile-time), and took the resulting output as further input to
incorporate into the D program. Basically, it was as if the D
preprocessor suddenly was a metaprogramming framework. And it worked,
not as a special hack, but as a corollary of very cleanly worked out
D-language rules for purity and immutability, plus the fact that much of
the D standard libraries (including the D compiler) were pure enough to
play these games with.
Reference: https://dlang.org/spec/function.html#pure-functions
(I see from dlang.org they have fancy templates now. They probably
interoperate well with ad hoc compile-time computations. The C++
constexpr stuff is moving that way too, I guess.)
Also, unlike a compiled language, we have a virtual machine that can (in
principle) be asked to verify purity of methods on the fly. This means
we can (in principle) have pure functions which are separately linked,
and do not need to be dumped into the current compilation. Of course
native methods and Panama downcalls would have to either be rejected or
manually certified, but that’s all part of the game.
> However, "constexpr" only deals with language-level constructs. For
> Java, perhaps we need something that includes a wider set of
> environmental dependencies.
Yes. (I have thought for some years that our keyword `const` has been
waiting to be used to annotate time-shifted computations. That’s just
bikeshedding of course.) I think, given Java’s embrace of dynamic
linking, it might make sense to define an idea of a time-shifted *value*
as well as a time-shifted expression or statement. By that I mean a
normal method could (perhaps) declare some but not all of its
*parameters* as `static` (or `constexpr` or whatever) with the meaning
that it is requesting that the corresponding actual arguments be
time-shifted (if possible) at every invocation point of that method.
Then a dynamically linked method could still partially play the
time-shifting game, in some of its parameters. (And similarly for local
variables. Sort of a “better static” with a dependency-driven
initialization order.) If a method’s formal parameter is marked
`static`, then expressions using that parameter inside the method are
also candidates for early evaluation. (This means the JVM or somebody
has to keep track of separate derived values for each method call site.
Doable but tricky.) This might give a framework to thread through all
the pre-evaluated values, through an application workload, without
disrupting the logic by partitioning it into disjoint “before” and
“after” phases.
And I think all of the above works about as well, not only for
time-shifting back in time to pre-evaluation in jlink, but also for
time-shifting forward in time to lazy evaluation. Java already has lots
of lazy evaluation in it, notably on-demand class initialization and
(under the covers) condy/indy. If we had a way to mark program portions
as time-shiftable, that would naturally parley out into a way to work
with lazy computations, as well as pre-evaluated ones.
This is the way I would prefer to handle recurrent requests (from me and
others) for APIs which help string templates to support syntax-specific
validation (SQL, XML, etc.). Such validation, for a constant template,
should happen as early as possible, ideally in the IDE, and certainly at
jlink time. Time-shifting can be a foundation for static validation.
More information about the leyden-dev
mailing list