2

I want to pre-process an OCaml snippet and make some modifications on the snippet, based on the type of certain expressions. For example, if the snippet has:

(f [1;2;3])

I would add another parameter to f like:

(f [1;2;3] [[0]])

.

But if I see something like:

(f ["a"; "b"])

Then I might want to:

(f ["a"; "b"] [[""]])

I was looking at camlp4, though I am not thorough with it; I think camlp4 doesn't have type information about the expressions.

Is there any way I can do this? Thanks!

Saswat Padhi
  • 6,044
  • 4
  • 20
  • 25

2 Answers2

2

CamlP4 is a preprocessor in the parse tree level which is not yet type-checked. Therefore writing type-dependent behaviour is ... not impossible but very hard: you need to send P4 parse tree to your probably modified OCaml type-checker then retrieve the typed AST from it, then translate it back to P4's untyped tree, somehow. P4's special AST data type makes this extremely hard to implement. In addition, people are now moving away from P4 :-(

OCaml preprocessing with types is much easier with its new -ppx framework, since it has better accesses to the compiler internals. It is not very easy but enough feasible. If you really want your type dependent preprocessing I recommend to use ppx. Main taksks are:

  • Send an untyped Parsetree AST to OCaml's type checker (probably with some modification)
  • Get its fully typed Typedtree AST then add what you want: in your case, adding more arguments
  • Translate the typed AST back to Parsetree using Untypeast module
  • Output the final Parsetree as the preprocessing result.

https://bitbucket.org/camlspotter/compiler-libs-hack explains how to implement such a typeful ppx preprocessor. I hope it helps you.

camlspotter
  • 8,990
  • 23
  • 27
0

This kind of type-based transformation is very fragile, for example what do you do with:

f []

or

let g x = f x

If you only need it to work for arguments that are constant literal expressions (which both your examples are), then you could do something with camlp4 or ppx. (ppx for preference because it is a simpler approach, but it only works from OCaml version 4.02).

So with ppx you could find every use of f applied to some literal expression and add the corresponding extra argument. Personally, I think this kind of preprocessing should be obvious in the code, so I would probably use:

[%f [1; 2; 3]]

rather than:

f [1; 2; 3]

for the syntax (the [%id ...] syntax was added in 4.02 specifically for use in syntax extensions).

Leo White
  • 1,131
  • 5
  • 9