Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml how to fix module name collisions

When making a toplevel, module names are not allowed to conflict with internal compiler libs.

What are some strategies for fixing this sorts of module name collisions?

Ideally, is it possible to pass some argument to ocamlc to instruct it to "mangle" the names of all the modules to use a custom prefix like MyProject_? (from the perspective of the OCaml ABI, not literally changing source files)

Full example below:

Sqrt.ml contains

let sqrt x = x ** 0.5

Sqrt.mli contains

val sqrt : float -> float

mktop contains

#!/bin/bash

ocamlc -c Sqrt.mli -o Sqrt.cmi 
ocamlc -c Sqrt.ml  -o Sqrt.cmo

ocamlmktop -o sqrt_toplevel Sqrt.cmo

And I can produce a toplevel containing the function I want.

% ./sqrt_toplevel
        OCaml version 4.04.0

# Sqrt.sqrt 4.5;;
- : float = 2.12132034355964239

If I rename the Sqrt module to Parse by changing the file names, the name conflicts with an internal library and the toplevel fails to link.

mktop is now

#!/bin/bash

ocamlc -c Parse.mli -o Parse.cmi 
ocamlc -c Parse.ml  -o Parse.cmo

ocamlmktop -o parse_toplevel Parse.cmo

with the other files simply renamed to Parse.ml and Parse.mli.

If I do this, I get a naming conflict with a compiler lib.

% ./mktop |& sed -e s:"$HOME":~:
File "Parse.cmo", line 1:
Warning 31: files Parse.cmo and ~/.opam/4.04.0/lib/ocaml/compiler-libs/ocamlcommon.cma(Parse) both define a module named Parse
File "_none_", line 1:
Error: Some fatal warnings were triggered (1 occurrences)
Exit 2
like image 674
Gregory Nisbet Avatar asked Jan 29 '23 15:01

Gregory Nisbet


1 Answers

I don't see a documented way to avoid this problem other than by using names that don't conflict with internal modules.

Here are Unix commands to list all the forbidden names, which is at least something:

$ cd ~/.opam/4.04.0/lib/ocaml/compiler-libs
$ ocamlobjinfo ocamlbytecomp.cma ocamlcommon.cma ocamltoplevel.cma |
    awk '/^Unit name:/ { print $3}' | sort

For me (using OCaml 4.03.0 right now) there are 96 forbidden names. I wrote a script to verify that all 96 are really forbidden.

As a side comment, the toplevel is in fact generated in spite of the reported error. And, in a quick test, it seems to work. The function Parse.sqrt (for example) exists and computes the right answers. But possibly there are problems that I just didn't happen to encounter.

like image 155
Jeffrey Scofield Avatar answered Feb 20 '23 22:02

Jeffrey Scofield