Enhancing expressions with mutability?
B. Blaser
bsrbnd at gmail.com
Tue Mar 10 21:03:40 UTC 2020
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: quote.patch
Type: text/x-patch
Size: 18205 bytes
Desc: not available
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20200310/54c5274c/quote-0001.patch>
More information about the compiler-dev
mailing list