Enhancing expressions with mutability?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Mar 23 14:31:00 UTC 2020
Hey Bernard,
cool stuff. Your patch seems to be missing the Term class, which is kind
of important to look at to see how it interoperates with javac.
That said, while the ideas you explore are interesting, I do not seem
them being applicable 'as is' to Java. That said, one direction which
overlaps a lot to what you describe here, especially in your derivative
example is support for the so called expression trees feature - C# for
example has it [1].
Expression trees gives the language a new super power, in that it allows
the static compiler to create a richer intermediate form for the
compiled expression (e.g. other than bytecode), which is then amenable
to further processing at runtime - e.g. we could take this IR and
compile it down to:
* regular bytecode - e.g. to generate a method handle
* assembly - very useful for native interop (a la Panama)
* GPU kernel - very useful for offloading computation to GPU or other
resources
At the same time, if the IR is expressive enough, you can do things like
differentiating functions and the likes, which are use cases very
important in machine learning.
So, my feeling is that, at some point, we'll start seeing some more
concrete experiments in that direction - stay tuned :-)
Maurizio
[1] -
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/
On 10/03/2020 21:03, B. Blaser wrote:
> Hi,
>
> Taking back the essential idea of the original publication on Lisp
> [1], I did the attached syntactic experiment [2] trying to bring some
> kind of mutability to expressions and thus giving more flexibility to
> the language. I hope this subject hasn't been covered too many times,
> otherwise I'd apologize for any disturbance.
>
> To build such mutable expressions, I've specified a new unary operator
> ` along with its resulting class 'java.lang.Term'. The quotation
> operator creates a 'Term' from any reference which can then be linked
> to other terms to finally be evaluated to the result of a function
> call for lambdas or the reference itself otherwise.
>
> Let's take some examples from the attached patch:
>
> + interface Get {
> + int op();
> + }
> +
> + interface Sum {
> + int op(int i, int j);
> + }
>
> + int a = 0, b = 0;
> + Sum s = (x, y) -> x + y;
>
> + public void run() {
> + Get a = () -> this.a;
> + Get b = () -> this.b;
> +
> + Term e1 = (`s).link(`a, `b);
> + this.a = 1; this.b = 2;
>
> The above lines create a mutable expression e1 from the sum lambda s
> of the getter a and b which can then be evaluated to:
>
> (Integer)e1.value() == 3
>
> or visualized as:
>
> e1.toString().equals("Sum( Get( ) Get( ) )")
>
> An interesting application similar to §3.g from [1] is the computation
> of the partial derivative of a sum involving the mutation of the
> initial expression to produce a new resulting one:
>
> + // Derivative of sum e with respect to r
> + Term derivative(Term e, Term r) {
> + if (e.terms.isEmpty()) {
> + return `Integer.valueOf(e.that == r.that ? 1 : 0);
> + }
> + else if(e.that == (`s).that) {
> + return (`s).link(derivative(e.terms.get(0), r),
> derivative(e.terms.get(1), r));
> + }
> + else throw new AssertionError();
> + }
>
> Invoking the above method like this:
>
> + Term e2 = derivative(e1, `a);
>
> creates the resulting derivative expression e2 which can then be evaluated to:
>
> (Integer)e2.value() == 1
>
> or visualized as:
>
> e2.toString().equals("Sum( `1 `0 )")
>
> Finally, we note that any term may be quoted to prevent its
> evaluation, for example:
>
> + Derivative d = this::derivative;
>
> + Term e3 = (`d).link(`e1, ``a);
>
> can be evaluated to:
>
> (Integer)((Term)e3.value()).value() == 1
>
> or visualized as:
>
> e3.toString().equals("Derivative( `Sum( Get( ) Get( ) ) `Get( ) )")
>
> Of course, one of our main concern is how much do we need this and a
> reasonable answer would probably be as much as we need Lisp's
> S-expressions but with similar or maybe better performance than
> external interpreters and a more homogeneous integration to the
> language.
>
> Any feedback about this experiment would be welcome!
>
> Thanks,
> Bernard
>
> [1] http://www-formal.stanford.edu/jmc/recursive.html
> [2] quote.patch
More information about the compiler-dev
mailing list