# Dune and module initialization side effects

**URL:** <https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520>\
**Category:** Learning\
**Tags:** dune\
**Created:** [October 9, 2019, 2:16pm UTC](https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520 "2019-10-09T14:16:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![martinslota](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/martinslota/32/1812_2.png) [@martinslota](https://discuss.ocaml.org/u/martinslota)\
**Post date:** [October 9, 2019, 2:16pm UTC](https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520/1 "2019-10-09T14:16:55Z")

</div>

I came across an arrangement of libraries where using `dune` produces confusing results (well, at least to me).

The fully functioning (and somewhat minimized) example of this can be found at [https://github.com/martinslota/ocuzzle-module-initialization](https://github.com/martinslota/ocuzzle-module-initialization). It’s a bit hard to present succinctly because it seems related to the way linking does or does not happen. But here’s an attempt to paste it here all in one spot:

File: `q_and_a/q_and_a.ml`

```auto
module type Question = sig
  val question : string
end

module Make_question () : Question = struct
  let question = "How much is 6 * 9?"
end

module Make_answer (Q : Question) = struct
  let () = Printf.printf "Making answer for question: %s\n" Q.question

  let answer = 42
end

module Question : Question = struct
  let question = "What's on your mind?"
end

```

File: `q_and_a/dune`:

```auto
(library
  (name q_and_a))

```

File: `cases/case1.ml`

```auto
module Question = Q_and_a.Make_question ()
module Answer = Q_and_a.Make_answer (Question)

```

File: `cases/case2.ml`

```auto
module Question = Q_and_a.Question
module Answer = Q_and_a.Make_answer (Question)

```

File: `cases/dune`

```auto
(library
  (name cases)
  ; (library_flags (:standard -linkall))
  (libraries q_and_a))

```

File: `mystery.ml`

```auto
let () =
  Printf.printf "Case 1 question: %s\n" Cases.Case1.Question.question;
  Printf.printf "Case 2 question: %s\n" Cases.Case2.Question.question

```

File: `dune`:

```auto
(executable 
  (name mystery)
  (libraries cases))

```

If you run this, you should see the following:

```auto
$ dune exec mystery/mystery.exe
Making answer for question: How much is 6 * 9?
Case 1 question: How much is 6 * 9?
Case 2 question: What's on your mind?

```

However, if you uncomment the `; (library_flags (:standard -linkall))` line above, then you should see this instead:

```auto
$ dune exec mystery/mystery.exe
Making answer for question: What's on your mind?
Making answer for question: How much is 6 * 9?
Case 1 question: How much is 6 * 9?
Case 2 question: What's on your mind?

```

Is this the expected behaviour?

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [October 9, 2019, 9:16pm UTC](https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520/2 "2019-10-09T21:16:44Z")

</div>

It is the expected behavior when compiling with `-no-alias-deps` (which is the case with dune) due to module aliases.

Indeed, in `mysterious.ml` third line:

```ocaml
     Printf.printf "Case 2 question: %s\n" Cases.Case2.Question.question

```

the module `Cases.Case2.Question` is a module alias for `Q_and_A.Question`. Thus, the identifier `Cases.Case2.Question.question` is directly translated to `Q_and_A.Question.question` . Consequently, the `Mysterious` module does not really depend on the intermediary module `Case2` and the initialization of `Case2` is skipped without `-linkall`.

A somewhat shorter reproduction case would be

```auto
(* core.ml *)
let x = 0

```

```auto
(* relay.ml *)
module Core = Core
;; Format.printf "Relay was initialized@."

```

```auto
(* main.ml *)
Format.printf "Core.x=%d" Relay.Core.x

```

Then the following compiles:

```bash
$ ocamlc -a core.ml -o core.cma
$ ocamlc -a relay.ml -o relay.cma
$ ocamlc -no-alias-deps -o main core.cma relay.cma main.ml

```

However, the `Relay` initialization is completely skipped, because it is not necessary to link any module in the `relay.cma` archive, and just

```bash
$ ocamlc -no-alias-deps -o main core.cma main.ml

```

works fine.

---

<div class="post-metadata">

**Author:** ![martinslota](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/martinslota/32/1812_2.png) [@martinslota](https://discuss.ocaml.org/u/martinslota)\
**Post date:** [October 12, 2019, 2:22pm UTC](https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520/3 "2019-10-12T14:22:44Z")

</div>

Many thanks for this insight! I think I’ll need to go educate myself a bit more.

Do you know why `dune` uses `-no-alias-deps`?

---

<div class="post-metadata">

**Author:** ![martinslota](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/martinslota/32/1812_2.png) [@martinslota](https://discuss.ocaml.org/u/martinslota)\
**Post date:** [October 12, 2019, 2:25pm UTC](https://discuss.ocaml.org/t/dune-and-module-initialization-side-effects/4520/4 "2019-10-12T14:25:26Z")

</div>

I guess part of the answer to my own question is in this comment:

> <https://github.com/ocaml/dune/issues/660#issuecomment-377268692>
>
> Hi!
> I am building an executable that uses module aliases. Building works fine, but when the aliased module is modified, I get...
