Beginner. Trying to use dune for the first time

I’ve been programming for 40 years, so I’m not REALLY new. I’ve played with Ocaml off and on (mostly off) for a few years, and am trying to “get it” again, this time using dune. I have written a few lines of code that looks good to me, but ‘dune build’ isn’t happy. Please tell me what I’m doing wrong:

I created a new project with ‘dune init proj lisp’. I wrote a short main program in lisp/bin/main.ml:

let repl input =
print_endline “repl…”;
()

let () =
let input = Lex.make_input_stream stdin in
repl input

And a short module that I put in lib/lex.ml and lib/lex.mli:

type stream = {
mutable line_num : int;
mutable chr : char list;
chan : in_channel;
}

let make_input_stream input = { chr = ; line_num = 1; chan = input }

type stream = {
mutable line_num : int;
mutable chr : char list;
chan : in_channel;
}

val make_input_stream : in_channel → stream

What could be simpler? I do a ‘dune build’ and it says:

File “bin/main.ml”, line 6, characters 14-35:
6 | let input = Lex.make_input_stream stdin in
^^^^^^^^^^^^^^^^^^^^^
Error: Unbound module Lex

I’m SO confused. I can’t spot anything wrong. Please tell me what my error is.

1 Like

I’m assuming you probably need Lisp.Lex.make_input_stream or to put open Lisp at the top of your bin/main.ml file.

Edit: fixed the lib name. Also, I just double checked by making a small project as you describe and that’s your problem.

Yes, that fixed. Thank you. I had never seen that .. construction.

I have another not-really-related question now:

I’m trying to understand dune, and it seems complicated.

When I do a ‘dune build’, it makes an executable called main.exe. The bin/dune file says:

(executable
(public_name lisp)
(name main)
(libraries lib))

I want ‘dune build’ to build lisp.exe, not main.exe. Am I wrong to expect it to do that? Can I make some obvious change to make that happen? What is the effect of ‘(public_name lisp)’? Sounds like he knows it should be lisp.exe.

1 Like

Hello Terry, be sure to checkout the docs: Quickstart — Dune documentation

I would rename main and remove the public attribute which is not needed for beginners.

Also you can use triple back ticks to format your code nicely next time

1 Like

@benjamin-thomas, I don’t think use of public_name should be discouraged for beginners, esp since that configuration is part of the init command and getting started docs.

@Terry_Phelps, you should indeed be building an executable named lisp (no exe extension) thanks to the public name. It should be in your _build directory, but also you can run it with dune exec lisp. See the doc for the public_name field at executable — Dune documentation.

Imho the public_name field for executables is an unnecessary distraction for beginners and should be removed from getting started tutorials. It is not mentioned on the dune landing page which shows a tiny example: https://dune.build/

See also Draft tutorials on Modules, Functors and Libraries - #2 by yawaramin

Simplicity is super important when getting started. A 1-to-1 correspondence between the source file name and the target executable file name is the kind of simplicity that we should not easily pass up.

1 Like

I’m sure the docs and UX could be improved, as always. But AFAIK, having an entry point called main that compiles into an executable of a different name is a widely used convention. This is well documented in dune, expected by the current project generation tooling, and doesn’t add much complexity imo. Whether or not the public name field is too complicated for beginners to grok probably depends a lot on their background, and I’m sure this is a place where reasonable people can disagree.

In any case, imo answering questions asked by newcomers directly helps simplify the onboarding experience.