[Feedback request] Enhancing expressions with mutability? (other use cases)

B. Blaser bsrbnd at gmail.com
Thu Mar 12 17:36:53 UTC 2020


To go a bit further, it'd be also possible to add another field to the
'Term' class representing the name of any quoted identifier, which can
concretely be made in 'Lower' by adding a couple of lines like
'makeLit(syms.stringType, ((JCIdent _or_
JCFieldAccess)arg).name.toString())' (I can share the full diff with
the previous 'quote.patch' if requested). We can then use it like '(`d
_or_ `this.d).name.equals("d")' in our initial example.

So, not to misunderstand me, this isn't a meta-programming facility by
itself but a fortunate consequence of the quotation operator which
might be used to considerably reduce the amount of code in certain
situations like persistence frameworks. And note also that mutable
expressions might be used to build queries using a more declarative
fashion, for example.

Isn't that still a direction which is worth exploring?

Thanks,
Bernard

On Tue, 10 Mar 2020 at 22:03, B. Blaser <bsrbnd at gmail.com> 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