[wg-camlp4] My uses of syntax extension

Alain Frisch alain at frisch.fr
Mon Jan 28 12:04:28 GMT 2013


On 01/25/2013 08:38 PM, Török Edwin wrote:
> * camlp4o     - for better syntax errors (see http://caml.inria.fr/mantis/view.php?id=5068). This is a time-saver during development

Interesting.  It would certainly be useful to improve OCaml syntax error 
messages.  There has been some improvements recently, with the addition 
of some explicit error rules, but more work (or maybe a different 
approach as the one you suggest in the note of this ticket) would be needed.

Of course, nothing will prevent you from continuing using camlp4 instead 
of the official OCaml parser, as a "local convenience" (code you might 
distribute will not depend on camlp4, at least if you don't start 
relying on differences between camlp4's ocaml parser and the official one).

> * js_of_ocaml - (blogpost says its not really needed if a different operator would be used)

Indeed, it was our first use of -ppx here at LexiFi.  Some version of it 
can be found there:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/trunk/experimental/frisch/js_syntax.ml?revision=12932&view=markup

Basically, instead of introducing new syntax (o ## m) to access, say, a 
Javascript property, we ask the user to write:

   JVS.(o.m)

In the scope of a local-open on the pseudo JVS module name, we interpret 
a few syntactic constructs as meaning something else.  We did the 
minimum work required to allow us playing with js_of_ocaml as part of an 
internship exploratory project.  Hopefully, the js_of_ocaml folks will 
pick up on that and provide all the required syntactic support, 
including for the creation of JS objects and so on.  (We could for 
instance use the following syntax: JVS.(object ... end).)

Note that we have reused the compact syntax for local opens in order to 
define a special "scope" where some constructions are interpreted 
differently.  Maybe we should keep two different kinds of node in the 
Parsetree to distinguish "let open M in e" from "M.(e)".  Or maybe we 
should introduce explicitly another kind of "named scope" to the OCaml 
grammar, to be interpreted by -ppx rewriters  (and this could be 
available not only for expressions, but also for other entities like 
patterns, types, etc).  Or maybe we can find a nice syntax for 
"attributes" which could be used for this kind of purposes.  Or is the 
solution based on piggy-backing the syntax for local opens just fine? 
Comments are welcome!


> * bisect      - haven't figured how to use ppx from oasis/ocamlfind, The camlp4 one is as simple as:
> 	$(SETUP) -build -tag pkg_bisect -tag pkg_str -tag syntax_camlp4o -tag syntax_bisect_pp $(BUILDFLAGS)

We use the -ppx version of Bisect here.  This is probably not supported 
by ocamlfind right now.  We simply add the following command-line options:

  * for compiling:
     -ppx ..../bisect_ppx$(EXE)	

  * for linking:
     -I <path_to_bisect>  bisect.cma (or .cmxa)


> camlp4 syntax extensions needed to build libraries that I use:
> lwt, tyxml (needs camlp4of), camlp4.macro

tyxml: my understanding is that support for quotations (with 
anti-quotations in them?) would be enough.

camlp4.macro:  does this refer to pa_macro?  It seems that this is more 
about conditional compilation than proper macro expansion.  I suspect 
that conditional compilation is used rarely enough in OCaml project, so 
that a slightly more verbose syntax would not a big deal.  Do you confirm?

See 
http://www.lexifi.com/blog/syntax-extensions-without-camlp4-lets-do-it 
for a -ppx based version of conditional compilation.  The syntax is:

   include IFDEF(SYMBOL)(struct
      ... (* structure items in case SYMBOL is defined *)
   end)(struct
      ... (* structure items in case SYMBOL is not defined *)
   end)



For lwt: this project (and similar ones) might justify some special 
extensions to the concrete grammar.  There are basically two approaches 
are:  either support "let-fix" operators directly in the OCaml or just 
extend the syntax and let -ppx rewriters to the job.  There are several 
variations around the first solution, but we could for instance allow 
defining let-fix operators like:

   let (let***) x f = ...

and then use them as:

  let*** x = e1 in e2

which would be just sugar for:

   (let***) e1 (fun x -> e2)

(here I've assumed that let-fix operators are made of the characters 
"l", "e", "t" followed by an non-empty sequence of "operator" characters.)

The second approach is simply to extend the parser to accept

   let*** x = e1 in e2

and represent this explicitly in the Parsetree (a -ppx rewriter will 
then have to be used to rewrite that to something the type-checker accepts).

Both approaches can be combined: a default behavior for let-fix 
operators, but with an explicit representation in the Parsetree, 
allowing -ppx rewriters to provide a different interpretation. 
Typically, lwt has a notion of parallel binding, which would probably 
require some custom support (-ppx).


> Syntax extensions I considered using but never got around to:
> pa-monad (didn't really need it), bitstring

pa-monad: Wojciech Meyer announced omonad, a -ppx version of pa_monad.

bitstring: see my comment in another post.  Conceptually, this is quite 
similar to Sedlex.  The question is whether we can come up with a 
reasonable syntax (either with standard patterns, or maybe with pattern 
quotations?).

> Also when initially learning OCaml I have used the revised syntax (camlp4r) quite heavily.
> Nowadays I write everything in the original syntax.
> While I wouldn't miss the revised syntax, I do think that its much easier to first learn the revised syntax so it'd be nice
> if the camlp4 replacement provided that as well.

See the other post.  -ppx is really aimed at "syntax extensions"
which are more about code generation (type-conv, sedlex, ...) or code 
manipulation (conditional compilation, ...) than actual changes to the 
concrete syntax.  When the concrete syntax is the main objective, I can 
see two different cases:

   - Small local syntactic additions, like the one implemented by 
pa_lwt: we should think about generic extension points in the official 
parser to support them (together with -ppx rewriters).  Or even direct 
support in the compiler when it makes sense (e.g. direct support for 
local opens is much better than pa_openin).

   - More pervasive changes to the whole language grammar (like the 
revised syntax):  this is really what -pp is good at, and I personally 
don't have plans to propose an alternative for these cases.  It's good 
that you can experiment with parsers written with any technology.  That 
said, while I can admit that alternative syntaxes are interesting for 
experiments or educational purposes, I believe that released source code 
(libraries, applications) should stick to the official syntax, to avoid 
fragmentation of the community and issues with editors/IDE.



Alain


More information about the wg-camlp4 mailing list