Cannot open module already loaded into utop


#1

I cannot get a locally compiled library (from https://github.com/selectel/alberto) into utop, here is my session:

Welcome to utop version 2.0.1 (using OCaml version 4.05.0)!

Findlib has been successfully loaded. Additional directives:
  #require "package";;      to load a package
  #list;;                   to list the available packages
  #camlp4o;;                to load camlp4 (standard syntax)
  #camlp4r;;                to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();;         to force that packages will be reloaded
  #thread;;                 to enable threads

utop was built without camlp4 support.
utop[0]> open Core;;
utop[1]> #load "/home/jon/app/ocaml-jbuilder/_build/default/alberto/src/alberto.cmo";;
utop[2]> open Alberto;;
Error: Unbound module Alberto
utop[3]> 

Needless to say the module name “Alberto” is correct, and my code using that module name compiles successfully.

Can anyone explain the problem / fix?

Thanks.


#2

I see this behavior when using #load with a full path in the toplevel.

$ ocaml
. . .
# #load "/Users/jeffsco/tryload/m.cmo";;
# open M;;
Error: Unbound module M

The problem goes away if I specify the directory with -I and use just the module name in #load:

$ ocaml -I /Users/jeffsco/tryload
# #load "m.cmo";;
# open M;;
#

(However, if the full path happens to be the current directory, the first example works in my tests.)

I don’t know if utop works the same, but this is suggestive at least.


#3

brilliant - thanks; I would never have guessed!

I’m using within emacs but the #directory directive placed into ~/.ocamlinit achieved the same effect.


#4

The OCaml compiler needs a compiled interface (.cmi) for every module you refer to. Bytecode object files (.cmo) only seem to contain bytecode, identifiers aren’t even stored there.

You can test this easily by compiling let my_f x = x+1 and looking for my_f in both generated files :wink: