[wg-camlp4] My uses of syntax extension

Jeremy Yallop yallop at gmail.com
Tue Jan 29 14:00:46 GMT 2013


On 29 January 2013 13:17, Leo White <lpw25 at cam.ac.uk> wrote:
> quotations should also be used in for extensions that are, as Gabriel put
> it, "mostly valid OCaml code".

I'd like to offer an opposing view: quotations are for use in
metaprogramming, and should not appear in user code (including code
that makes use of syntax extensions) at all.

Quotations turn code into values that can be processed by user code.
The idea of a quotation is to prevent code being evaluated
immediately, instead making it available to the quoting program as a
manipulable value.  I don't think that's what we're aiming for here;
instead, we're aiming to make it easier to hook syntax transformers
into the compiler.

Perhaps some examples will make the distinction clearer.

Here's a Campl4 quotation that builds an AST fragment:

      let x = <:expr< y + 1 >>

The value bound to x is now available for use in the program in which
the quotation appears.  You can analyse it, embed it in a larger AST,
print it, etc.

Here's a MetaOCaml quotation that builds a code value:

      let x = .< y + 1 >.

Again, the value bound to x is now available for use in the program in
which the quotation appears.  You can compile it, include it in a
larger piece of code, etc.

Here's a string quotation:

      let x = " y + 1 "

Once again, the value bound to x is available for use in the program
in which the quotation appears.  You can tokenize it, print it, etc.

In each case above, omitting the quotation delimiters would cause
immediate evaluation of the quoted code.  The reason for quoting is to
prevent evaluation and make the code available as a value instead.

Now consider the arrow notation example:

      let g = <:proc< x -> y <- f -< x + 1;
                           return -< y + 2 >>

Here the aim is quite different: we don't want to prevent immediate
evaluation; instead, we want to transform the syntax *for* immediate
evaluation.  We don't want g to be bound to some user-manipulable
representation of the code.  Instead, we want the *implementation* to
consume the desugared notation, type check it and bind the result of
evaluating it to g.  The distinction between user-consumable and
implementation-consumable code is obscured if we use quotations for
both in the source language.  Both quotations and syntax extensions
are useful, but let's use different notations for them.  For example,
using Alain's proposal, we might write the following for the arrow
notation fragment:

      let g = (@proc) x => (y <= f =< x + 1;
                            return =< y + 2)

Jeremy


More information about the wg-camlp4 mailing list