[wg-camlp4] On domain-specific foreign syntaxes
Leo White
lpw25 at cam.ac.uk
Fri Feb 1 11:02:55 GMT 2013
>We can choose:
>
>type annotation = expression
>and extension = expression
>
>or maybe:
>
>type annotation = string * expression
>and extension = string * expression
>
>I think I prefer to use bare expressions, and encode in them the
>"markers", because this does not force to hard-code the nature of
>markers. An argument in favor of keeping an explicit "string" is to
>define more explicitly the "namespace" of the extension, though.
I think that it is very important to define the "namespace" of extensions.
I was thinking something like:
type annotation = expression
and extension = longident * expression option
So the extension has the same type as a constructor application. I don't
think annotations should necessarily be namespaced because they will
probably be very useful within an extension, in which case they will
already be namespaced by that extension.
>I don't believe we should add a further distinction between the
>annotations which can actually be ignored by the compiler and those on
>which the type-checker must complain. This can be left to a choice of
>syntax which combines an annotation and an extension.
I agree.
>Similarly, I'm not sure we should hard-code/enforce the fact that an AST
>mapper should only be able to expand "under" extensions. Extensions
>could also be used as markers which can trigger "local enough"
>rewriting. (See examples "Bolt" and "PG'OCaml" below.)
I agree.
>Only to fix the ideas, let's give some examples, assuming the following
>syntax:
>
> (# e) -> extension
> ... (+ e) -> annotation (with light postfix syntax)
> (@ e) ... -> annotation (with light prefix syntax)
>
> (@(e) ...) -> annotation (explicit scope, prefix syntax)
>
>and maybe a derived "non-ignorable annotation":
>
> ... (& e) === ... (+ (# e))
>
>and syntactic variants such as:
>
> let(+e) p = ... === (@ e)(let p = ...)
>
>and also something which combine an extension + quotation:
>
> (:id x[...]x) === (# id {x{...}x})
This certainly seems to be along the right lines. If we really prefer {, (
or [ for delimiters then perhaps:
Quotation: {x{ ... }x}
Extension: (:longid expr)
Annotation: (@ expr) (and maybe others for prefix etc.)
Then some abbreviated forms for common cases:
Quotation Extension:
{:longid x{ ... }x} == (:longid {x{ .. {x})
Let Extension:
let:longid foo = ... in ...
== (:longid let foo = ... in ...)
Match Extension:
match:longid expr with ...
== (:longid match expr with ...)
Type-Conv Annotation:
type foo = ... with longid( expr ), longid ...
== type foo = ... (@ longid expr) (@ longid) ...
We could provide special-cases in ast_mapper to make these abbreviated
forms particularly easy to work with.
The downside of this abbreviated syntax for quotation extensions (as
opposed to {:foo| ... |} )is that it does not provide an alternative
delimiter to "}". However it probably fits in better.
More information about the wg-camlp4
mailing list