Hi! I’d like to use OCaml for scripting in situation where I’d typically reach for a shell script otherwise. I’d like to avoid writing any dune-file boiler plate.
I’ve figured out that I can run .ml
files directly through the ocaml
toplevel (ocaml my_script.ml
). However, you quickly run into situations where you need non-core libraries (unix
, re
, …). For this, I’ve understood that you can use the top-level directives to load ocamlfind (which can be installed by e.g. opam
) which in turn adds the #require
directive with which you can load libraries in a portable manner:
(* Load the [#require] directive from topfind aka
findlib aka ocamlfind: *)
#use "topfind"
(* Load the [re] library: *)
#require "re"
(* Load the [unix] library: *)
#require "unix"
let () = (* [Re] and [Unix] are now available ... *)
...
The disadvantage now is that, as reported here and here, this file can now longer be analyzed with merlin, which reports Syntax error
on the top-level directives used the file above. This makes editing such scripts quite a pain since you no longer have all the conveniences enjoyed through merlin.
A workaround is posted in one of the issues linked above. Instead of using the top-level directives, their definitions can be in-lined in the script:
(* Equivalent to [#use "topfind"] *)
let () = Topdirs.dir_use Format.std_formatter "topfind"
(* Equivalent to [#require "re"] and [#require "unix"]: *)
let () = Topfind.load_deeply [ "re"; "unix" ]
let () = (* [Re] and [Unix] are now available as above ... *)
...
(I think this might require installing ocaml-compiler-libs.toplevel
first though.)
At this point, you only have to jump through a final hurdle to make the file analyzable by merlin. Merlin can’t figure out on it’s own that the re
and unix
libraries are used in the script. For this, we can add a PKG
directive to a .merlin
in the same folder as the script:
PKG findlib ocaml-compiler-libs.toplevel unix re
In conclusion,
- by using the inlined definitions of the top-level directives
#use
to load topfind, and then#require
to load non-core libraries; - by instructing
merlin
about the of the non-core libraries used through aPKG
directives in the.merlin
file,
we can now run the script as such ocaml my_script.ml
and edit it directly in e.g. emacs with IDE-capacities as provded by merlin.
Now, to my question: are there any easier ways achieve the above: single-file scripts, easy to run without compilation and merlin-powered editing?
I know about:
but I haven’t yet had the time to figure out how they can help me.