Newbie dune question

I’m trying to learn dune, and am finding that there’s a lot to learn. Can someone explain to me, or point me to the relevant dune docs, why it works this way:

Here’s what I have done:

  1. Created a new dune project: dune int proj test
  2. Changed the dune files in bin and lib to say “(libraries lib)” and “(name lib)”, respectively. (Because it makes more sense to me this way.)

I then tried 2 things. The first:

I created a file in lib called lib.ml, and put a function (func) there. In bin/main.ml, I “open Lib”, and the function is callable without having to use the filename, like:
let x = func 1 2

Then I changed the name of lib.ml to new.ml. Now, the function has to be called liek this:
let x = New.func 1 2

It seems odd to me that the rule is “If the filename matches the library name, you don’t have to code it. Otherwise, you do.”

Please tell me, or point me to docs about why this makes sense.

This is a little bit of “magic” that dune is adding to your structure.

That file lib/new.ml isn’t automatically available as Lib.New - what dune is doing is:

  1. Seeing that you don’t have a lib.ml in that directory
  2. Creating a template one that does something like module New = New

This means that Lib now exports New as a sub-module.

If you create your own lib.ml (a file matching the directory) then dune will assume you know what you are doing and skip the above.

That lets you choose to not export all the sub-modules or to rename them etc. You might find it helpful to try doing that to “bed down” the understanding.

It does catch you out the first time though (or at least it caught me out) because you are learning a lot of things all at once.

2 Likes

For reference, see the Dune docs on libraries (emphasis added):

<library-name> is the real name of the library. It determines the names of the archive files generated for the library as well as the module name under which the library will be available, unless (wrapped false) is used (see below). It must be a valid OCaml module name, but it doesn’t need to start with an uppercase letter.

For instance, the modules of a library named foo will be available as Foo.XXX, outside of foo itself; however, it is allowed to write an explicit Foo module, which will be the library interface. You are free to expose only the modules you want.

Excellent answer. Thank you.

Please confirm (or deny) my understanding, which is what my testing seems to show:

  1. If there is no lib.ml in my library named “lib”, then all the *.ml files in the library are available as Lib..
  2. If there IS a lib.ml file, then any other *.ml files in there are not available in my main program at all. (Maybe there’s another trick to make that work.

OH. I just discovered the trick, by reading your response one more time. In lib.ml, I put the line module Other = Other. that makes other.ml available as Lib.Other.

1 Like

Exactly, and you can further restrict things then with a lib.mli if you want.

I think this is all dune-specific stuff though, if you are just using make and ocamlfind etc then you always have to write your own “top-level” module file.