Hello,
There’s something I don’t understand with (implicit) modules, compilation (dune), cma and the toplevel.
In Lib/i201.ml
, I’ve put this simple type definition:
type nombre = E of int
| R of float
| C of float*float
Then, thanks to this dune
file:
(library
(public_name inf201)
(name i201)
I can build my library inf201
successfully.
In the Lib/_build/default
directory, I try to load it in a toplevel:
default § ocaml i201.cma
OCaml version 4.06.1
Findlib has been successfully loaded.../...
# I201.E 1 ;;
Error: Unbound module I201
Same problem with #load
:
default § ocaml
OCaml version 4.06.1
Findlib has been successfully loaded.../...
# #load "i201.cma" ;;
# I201.E 1 ;;
Error: Unbound module I201
I guess there’s something obvious I’ve missed.
1 Like
It seems that the cmi file is not visible from the toplevel. Rather than struggle with finding the right file, you can use dune utop Lib
to launch utop with your library already loaded.
Thanks for your reply. Indeed, dune utop
works as expected:
default § dune utop
Entering directory '/.../Lib'
────────┬─────────────────────────────────────────────────────────────┬─────────
│ Welcome to utop version 2.2.0 (using OCaml version 4.06.1)! │
└─────────────────────────────────────────────────────────────┘
utop # I201.E 1 ;;
- : I201.nombre = I201.E 1
But the library I intend to develop will be used in a scholar environment where utop won’t be available.
I wonder if this problem has to do with the absence of .mli and/or explicit module definition.
Your problem mostly comes from trying to use an uninstalled library. It seems fine to use utop
for your own test. If you want to test in the student environment, you could pin the library with opam. Or a more manual solution would be to use dune build -p inf201
and then use the file to be installed in _build/install
.
The way ocaml works, there are two sets of files: the code, and the “module descriptions”. Both need to be present for the toplevel to work. As others have pointed out, dune utop will take care of loading them. But there are a number of mechanisms. There’s the toplevel’s source-path directive ("#directory"): you can give the directory containing the CMI files you wish to have available. You can also package your code and install it via findlib, and then use the findlib topfind/require directives,e.g.
#use "topfind";;
#require "utils" ;;
etc.
I think the #directory mechanism is the most basic; all the others (I suspect) build on top of that (written by different people/groups at different times).
I was thinking about this: Have you thought-thru your environmental assumptions? I’ve been building caml-light/ocaml setups for … decades, and the “opam” way of doing it is hands-down the simplest I’ve seen. If you’re able to pre-req opam, then, well, “dune utop” is as easy to install as anything else.