Dune build -w; dune utop; edit - recompile - reload

I have a simple OCaml project.

dune build -w works
dune utop works

I can’t use both at the same time.

I’m wondering if there is a way to have the following work flow:

  1. I’m editing in VIM

  2. I have a dune build -w running, which recompiles on source change.

  3. (I don’t have this part yet). I have dune utop running, then every time that dune build -w succeeds, it causes the dune utop to reload the latest modules. (If I end up losing some state, that’s fine ,I’ll develop techniques to work around it.)

So the overall work flow is:

  1. I write some code in vim, hit :w

  2. dune build -w tries to recompile; on error, it displays error

  3. if step 2 succeeds, dune utop reloads the new module into the repl

1 Like

I wanted to do this a few days ago, you may find a few useful ideas here: Can I "reset" my REPL? - #3 by benjamin-thomas

Since then, I found another neat option which is good for little examples.

It’s document here: Toplevel Integration — Dune documentation

And not very obvious from an outsider’s perspective. In short:

  1. you write an .ocamlinit file in one of your project’s sub-directories.
  2. You add only this line. #use_output "dune ocaml top";;
  3. Now you can execute utop from this sub-directory (just utop, no dune prefix)

On entering utop, your module will be compiled “automagically”, no need for dune build.

Just ctrl+d out of utop then re-enter and you’ll have you’re latest module available, newly compiled (the recompilation is very fast).

I haven’t played with this technique extensively yet but it feels great for little examples and code exploration.

1 Like

Sorry to be pedantic, I’m new to the OCaml toolchain and want to make sure I understand this correctly.

Previously, I was running with “dune build -w”, which has the benefit that on every Vim save, it auto recompiles.

Does the approach you are suggesting eliminate this? I.e. I need to manually trigger recompile by killing utop and rerunning it ?

One situation where this is inconvenient is that if I am doing a refactoring and there are many errors, with the “dune build-w” approach, I fix an error, I get next error; whereas with this approach, I have to constantly re-trigger the compile myself.

Sure. I’m new to OCaml myself so take what I’m saying with a grain of salt :slight_smile:

What you can do:

  • clone this repo
  • cd lib/chapter16/rev/
    • notice the hidden .ocamlinit file
    • rm ./lib/rev_lib.mli # remove the interface to make the whole module “open” to utop.
    • editor ./lib/rev_lib.ml
      • add this line: let hello = 1 [@@warning "-32"]
  • launch utop
    • you can now access this new function: Rev_lib.hello;;

You will see that entering utop will actually generate a _build folder at the project’s root.

Each time you re-enter utop, the files in lib/chapter16/rev/ get rebuilt.

So you can continuously exit and re-enter your REPL that way: while true;do utop;sleep 1;done (press ctrl+d to exit and recompile)

Don’t ask me how this works though :smiley: , it’s…

Shia Labeouf Magic GIF

2 Likes