Bracket notation in metaocaml

A few major libraries like core_kernel and owl conflict with BER Metaocaml by defining a >. operator. As a consequence, the 4.07.1+BER switch cannot compile neither core_kernel nor owl, and of course no lib that depend on them. On top of that, merlin does not recognize metaocaml’s brackets. I was wondering if a new version of metaocaml relying on syntax extensions would help with these issues. Basically, .< 1 + .~x >. would be replaced by [%metaocaml.code 1 + [%e x]]. This wouldn’t completely solve the issue with merlin (since I guess there is a need for dedicated support in the incremental compiler), but we’d be fine with libraries redefining >..

Alternatively, since units compiled with metaocaml{c,opt} are compatible with those compiled by ocaml{c,opt}, maybe metaocaml shouldn’t be distributed as a particular switch, but as a package providing the metaocaml compilers and interpreter, that could be called on specific files in a project, while using the usual compilers for the rest.

Maybe there are other approaches?

2 Likes

Indeed, see also https://github.com/janestreet/core_kernel/issues/96

FYI, we are considering removing these operators from Core_kernel. They would still be available in a separate library, but they won’t be exposed at the top level of Core_kernel any more, so this problem should come up less often.

merlin supports metaocaml syntax via EXT meta directive (but you need to add extra (not needed for compilation) open Trx for it to recognize metaocaml “standard” library)

We removed some operators in batteries v3 for this reason.
So, batteries v3 will be BER Metaocaml-friendly.

Thanks for the hint! Merlin still complains after opening Trx with an Unbound module _.Meta error. Also would you know a trick to have dune add this directive when generating its .merlin file (otherwise the manual modification gets overwritten)?

+1 for merlin support via dune.

You are talking about compilation, but can you correctly evaluate a MetaOCaml expression within the Toplevel?
With Emacs/Tuareg, I can evaluate all expressions except the bracketted ones:

(* let a = .<1>.
    is not correctly evaluated if sent from the buffer: 
    the '>.' is not parsed  *)
# let a = .<1;;
Characters 11-13:
  let a = .<1;;
             ^^
Error: Syntax error
# a;;
Characters 0-1:

(* so a is unbound *)
  a;;
  ^
Error: Unbound value a

(* let a = .<1>.
    is correctly manually evaluated  in the metaocaml Toplevel *)
# let a = .<1>.;;
val a : int code = .<1>. 

BTW

.< 1 + .~x >.

is much more elegant and concise than the verbose

[%metaocaml.code 1 + [%e x]]

We should preserve it.

I didn’t try, but I believe you want to use flags. It should look like this: (flags (:standard -open Trx)).

This can be done in a specific executable/libraries stanza, or with the env.

(env (_ (flags (:standard -open Trx))))
1 Like

Thanks, that’s helpful since otherwise the compiler complains about unused open Trx statements. But I was referring to the “EXT meta” directive, I’m not sure there is a means to add this from dune in .merlin.

Just noticed containers also defines a >. operator …

shoot. that was introduced relatively recently as a nice and short notation for non-polymorphic Float compare operations, along with =., <. etc, i believe.

no, I don’t. Guess should be raised with dune github. In some codebase I have seen unspeakable hacks of postprocessing .merlin after build step to keep certain flags/options.