# Draft tutorials on Modules, Functors and Libraries

**URL:** <https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686>\
**Category:** Learning\
**Tags:** module, functor, learn-ocaml, tutorial, dune\
**Created:** [December 20, 2023, 2:33pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686 "2023-12-20T14:33:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cuihtlauac](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cuihtlauac/32/3638_2.png) [@cuihtlauac](https://discuss.ocaml.org/u/cuihtlauac)\
**Post date:** [December 20, 2023, 2:33pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/1 "2023-12-20T14:33:12Z")

</div>

Dear OCamlers,

The series on [ocaml.org](http://ocaml.org) tutorial updates continue. This time, the [ocaml.org](http://ocaml.org) team has three drafts related to the module system in a single pull request. We want your feedback on it:

- GH PR: [Update Modules and Functors Tutorials #1778](https://github.com/ocaml/ocaml.org/pull/1778)
- Online drafts:
  - [Modules](https://staging.ocaml.org/docs/modules) — This is a refresh of the previous version
  - [Functors](https://staging.ocaml.org/docs/functors) — This is mostly new material
  - [Libraries With Dune](https://staging.ocaml.org/docs/libraries-dune) — This is entirely new material

The **target audience** is developers learning OCaml. No functional programming knowledge is assumed. However, it comes after the “Get Started” series:

1. [Installing OCaml](https://ocaml.org/docs/installing-ocaml)
2. [A Tour of OCaml](https://ocaml.org/docs/tour-of-ocaml)
3. [Your First OCaml Program](https://ocaml.org/docs/your-first-program)

They also require the first two tutorials of the “Introduction” series as prerequisites:

1. [Values and Functions](https://ocaml.org/docs/values-and-functions)
2. [Basic Datatypes and Pattern Matching](https://ocaml.org/docs/basic-data-types)

As the previously announced drafts, these also contain overlooked issues. We want to make it better with your help.

Share your feedback on GitHub or here, but do not use the “Contribute” link at the bottom of the staging pages.

Hope it helps

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [December 20, 2023, 6:24pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/2 "2023-12-20T18:24:32Z")

</div>

Sharing some feedback here for [Libraries With Dune · OCaml Documentation](https://staging.ocaml.org/docs/libraries-dune)

1. There’s no need for `touch mixtli.opam` as dune will generate the opam file
2. I’d suggest not to introduce a new domain (clouds and their names) when teaching dune concepts, it will unnecessarily distract from the material. We can stick to simple concepts that everyone is familiar with, like say math (addition, subtraction, etc.: `let add x y = x + y` and so on)
3. There’s no pressing need to introduce `public_name` for the executable stanza, at the beginner level. We can just say that the executable name is the same as its main module
4. We should mention the most important reason for having wrapper modules for libraries, to avoid module name clashes, i.e. namespacing

Otherwise it looks good and is much needed.

---

<div class="post-metadata">

**Author:** ![cuihtlauac](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cuihtlauac/32/3638_2.png) [@cuihtlauac](https://discuss.ocaml.org/u/cuihtlauac)\
**Post date:** [December 21, 2023, 8:55am UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/3 "2023-12-21T08:55:49Z")

</div>

Thanks for your feedback @yawaramin, this is really helpful.

> - There’s no need for `touch mixtli.opam` as dune will generate the opam file

Good idea.

> - I’d suggest not to introduce a new domain (clouds and their names) when teaching dune concepts, it will unnecessarily distract from the material. We can stick to simple concepts that everyone is familiar with, like say math (addition, subtraction, etc.: `let add x y = x + y` and so on)

We are trying to minimize the number of math-based examples, that’s why strings were picked here.

We’re also trying to have refreshing examples, to avoid the _deja vu_ feeling from foo, bar, alice, bob and other canned examples. But if it turns out to be too much cognitive noise for the majority we’ll pick something else.

> - There’s no pressing need to introduce `public_name` for the executable stanza, at the beginner level.

But then we have to instruct learners to type `dune exec ./cloud.exe`, don’t we? Avoiding to explain that `./cloud.exe` is not a file name was the goal. Some beginners seem to have a hard time with this.

> We can just say that the executable name is the same as its main module

We are doing that in earlier tutorials which are using Dune (First Program and Functors). But since this tutorial is covering some Dune, I believe it is fit to introduce the different names and their roles.

> - We should mention the most important reason for having wrapper modules for libraries, to avoid module name clashes, i.e. namespacing

You are right, this is missing.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://discuss.ocaml.org/u/jbe)\
**Post date:** [December 21, 2023, 10:47am UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/4 "2023-12-21T10:47:47Z")

</div>

> [@cuihtlauac](#):
>
> They also require the first two tutorials of the “Introduction” series as prerequisites:
> 
> 1. […]
> 2. [Basic Datatypes and Pattern Matching](https://ocaml.org/docs/basic-data-types)

I know this isn’t part of the PR, but I started looking through everything, and I noticed this:

> #### Characters
> 
> Values of type `char` correspond to the 256 symbols of the Latin-1 set.

When I came to OCaml, this confused me. As far as I understand, it’s okay (and normal) to store UTF-8 in the `string` type, right? Thus:

```plaintext
# "Grüße".[2];;
- : char = '\195'

```

The char isn’t necessarily Latin-1 but could be just a part of an UTF-8 sequence.

If I have time, I’ll look through the rest too and see if I stumble upon anything else that confused me when getting into OCaml. (Thanks for all the work, I’m really excited about learning OCaml!)

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [December 21, 2023, 11:23am UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/5 "2023-12-21T11:23:01Z")

</div>

> [@jbe](#):
>
> As far as I understand, it’s okay (and normal) to store UTF-8 in the `string` type, right?

Indeed. That latin1 intepretation is an old-fashioned view that should not be propagated. The story is that `char` values are bytes (which for 0x20-0x7E you can specify by their corresponding US-ASCII literal if you fancy so), `string` values are immutable sequences of bytes, `bytes` values are mutable sequence of bytes. And that the recommended default way of interpreting `strings` or `bytes` as text if you need to is as UTF-8 encoded text.

This view can be found in the [documentation preamble](https://v2.ocaml.org/releases/5.1/api/String.html) of the String module.

---

<div class="post-metadata">

**Author:** ![cvine](https://avatars.discourse-cdn.com/v4/letter/c/90db22/32.png) [@cvine](https://discuss.ocaml.org/u/cvine)\
**Post date:** [December 21, 2023, 3:16pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/6 "2023-12-21T15:16:58Z")

</div>

> [@dbuenzli](#):
>
> The story is that `char` values are bytes (which for 0x20-0x7E you can specify by their corresponding US-ASCII literal if you fancy so), `string` values are immutable sequences of bytes, `bytes` values are mutable sequence of bytes.

That’s sort-of the story but the documentation is not wholly consistent with the view that `char` values are bytes. For example for the `int_of_char` function (and the `Char.code` function), the documentation reference states that these “Return the ASCII code of the argument”. In reality, those functions work over the entire byte range, not just the ASCII range.

**Edit:** And of course a similar point arises with respect to `char_of_int` and `Char.chr`.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://discuss.ocaml.org/u/jbe)\
**Post date:** [December 21, 2023, 6:26pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/7 "2023-12-21T18:26:34Z")

</div>

> [@cuihtlauac](#):
>
> - Online drafts:
> - [Modules](https://staging.ocaml.org/docs/modules) — This is a refresh of the previous version
> - […]

> #### File-Based Modules
> 
> In OCaml, every piece of code is wrapped into a module. Optionally, a module itself can be a submodule of another module, pretty much like directories in a file system.
> 
> When you write a program, let’s say using the two files `amodule.ml` and `bmodule.ml`, each automatically defines a module named `Amodule` and a module named `Bmodule`, which provides whatever you put into the files.

What I wondered about is how the “upcasing” actually works. As far as I understand, only the first letter is upcased. Thus a file name `foo_bar.ml` would define a module `Foo_bar` and a file name `fooBar.ml` would define a module `FooBar`, right?

Am I right that `FooBar.ml` would be a forbidden filename?

I think the idiomatic way for naming modules is to use underscores, not camel-case, right?

I think some information on that topics might be helpful, and perhaps also an _explicit_ note that the upcasing of the first letter (and the first letter only!) is done automatically.

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [December 21, 2023, 8:53pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/8 "2023-12-21T20:53:28Z")

</div>

> [@jbe](#):
>
> Am I right that `FooBar.ml` would be a forbidden filename?

No you can do that. Details about interaction between the file system and the module system is documented [here](https://v2.ocaml.org/manual/comp.html#s%3Amodules-file-system).

Though personally I rather avoid uppercase letters for starting source files. This gives an opportunity for other interesting files to stand out when you `ls` a directory (e.g. `Makefile`, `README`, etc.).

> [@jbe](#):
>
> I think the idiomatic way for naming modules is to use underscores, not camel-case, right?

That’s still disputed today :–) But personally I simply use [this algorithm](https://discuss.ocaml.org/t/module-files-module-names-and-capitalization/1025/2).

---

<div class="post-metadata">

**Author:** ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)\
**Post date:** [December 22, 2023, 12:45pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/9 "2023-12-22T12:45:35Z")

</div>

I like that functors are introduced using `Set`. I would have liked to see this motivated by explaining why we need functors: it is not possible to implement a container (like a set) over some data type just using polymorphism because we need access to additional properties (like order) that are unavailable. The set implementation needs to know more about the base data type and this additional knowledge is provided by the functor argument.

---

<div class="post-metadata">

**Author:** ![cuihtlauac](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cuihtlauac/32/3638_2.png) [@cuihtlauac](https://discuss.ocaml.org/u/cuihtlauac)\
**Post date:** [December 22, 2023, 1:09pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/10 "2023-12-22T13:09:34Z")

</div>

Thanks, @lindig; as a rule of thumb, we try to present things in this order:

1. Use
2. Define your own

This is why we start with `Set.Make`.

We also try to show examples first and give explanations second; this allows referring to the example in the explanations and limits abstract sentences.

The motivation is presented as an answer to: “Why is this a functor?” Therefore, it comes second:

> Most set operation implementations must use a comparison function. Using `Stdlib.compare` would make it impossible to use a user-defined comparison algorithm. Passing the comparison function as a higher-order parameter, as done in `Array.sort` , for example, would add a lot of boilerplate code. Providing set operations as a functor allows specifying the comparison function only once.

As usual, we’re open to suggestions and proposals.

---

<div class="post-metadata">

**Author:** ![cdaringe](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cdaringe/32/2419_2.png) [@cdaringe](https://discuss.ocaml.org/u/cdaringe)\
**Post date:** [December 24, 2023, 6:28pm UTC](https://discuss.ocaml.org/t/draft-tutorials-on-modules-functors-and-libraries/13686/11 "2023-12-24T18:28:40Z")

</div>

Keep up the good work. Read two of them top to bottom and both were great
