I’ve seen this in a few places. When I was setting up down
for my ocaml shell I added that to my ~/.ocamlinit
to make things “work”.
But what is it?
I’ve seen this in a few places. When I was setting up down
for my ocaml shell I added that to my ~/.ocamlinit
to make things “work”.
But what is it?
It is necessary to be able to use ocamlfind
from inside the toplevel.
When you install the ocamlfind
package, it installs a file called topfind
in the standard library directory. Inside this file there are commands to load the Findlib
library which in turn registers (using compiler-libs
hooks) the #require
directive and other related Findlib features, and prints a short help text when it is done.
Cheers,
Nicolas
To add only a tiny bit to @nojb 's to-the-point explanation: one might ask why this is necessary: why, after all, doesn’t OCaml come with a standard package-manager that’s built-into the toplevel (and compiler/linker). And the answer I like, is that OCaml doesn’t make those sorts of assumptions, and this is a good thing, b/c somebody might come along with something better than findlib/ocamlfind/#require, and if OCaml had chosen one package-manager, then it’d be tough for that newcomer to do something different.
And even so, if one finds having to type that text #use "topfind";;
onerous, one can always put it in one’s ~/.ocamlinit
file.
Lastly, I maintain camlp5. And camlp5 wants to add a few lines to topfind
– a few extra commands, basically. And it’s great that doing so is really simple.
I use utop as my REPL and I’ve never needed that. #require "..."
works for me directly.
Yes I’d previously used utop
without needing it (I guess utop does it implicitly?)
I really like the more minimal prompt and better tab completion UI from ocaml+down at the moment though.
Anyway I just wondered what it was, and “provides the #require
directive” answers it well.
I’ve quite happily added it to my ~/.ocamlinit
and can forget about it (I assume there’s no downside?)
Note though that the tab completion of down
is orders of magnitude dumber than utop
’s one: it does not consider scopes/open
. See this issue.
This is a misconception, this is not about package managing, this is about being able to load a compiled object and its dependencies in the toplevel.
You can try to convince me as much as you want that having no support for this is actually a great idea, there’s only one way in which I can see that: defective (and btw. why do it for C dependencies an not OCaml ones…)
There’s a second way: preprocessors. Camlp5’s preprocessing method is not achievable in the PPX design.
Another way that package-managers differ from just “find the library to link” is that (for instance with ppx_deriving) you can have a bunch of plugins (viz. show
, eq
, ord
, etc) and then you can have meta-packages like std
that pull a number of the named ones in.
If you really have to, then fake, nop dependencies are easy to introduce between modules:
let () = Sys.opaque_identity (fun () -> let module D = Yourdep in ()) ()
Alternatively that seem easy to control via simple include directories.
In fact since that other discussion made me look again into it, that was the model I was using in b0caml
: directories with modules therein (and the actual linking business done in a data-driven like manner like omod
does).