Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/tutorials/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ These tutorials are hands-on lessons to learn about Dune.

developing-with-dune/index
dune-package-management/index
oxcaml-parameterized-library/index
:::
119 changes: 119 additions & 0 deletions doc/tutorials/oxcaml-parameterized-library/implement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Implement a Library Parameter

Now we have our parameter, we have our interface. In this section, we will
focus on how to write a library that implements our parameter.

## Structure Our Project

As we did for the `parameter`, we are going to add a new directory in our
structure under `lib/`. We create a directory `impl/` under `lib/`. At the root
of the directory, we can run:

```{code-block} shell
mkdir -p lib/impl
```

## Creating an Implementation

As for the parameter, we start with our `lib/impl/dune`

:::{literalinclude} implement/lib/impl/dune
:language: dune
:::

To create an implementation, we write two files:
- The first one is `lib/impl/impl.ml`. It contains the implementation.
- The second one is `lib/impl/impl.mli`. It contains the interface of the implementation.


We define an additional `create` function to send our element in the abstract
type. Our project now implements a parameter.

:::{literalinclude} implement/lib/impl/impl.mli
:language: ocaml
:::

To have an abstract interface, we define an `mli` file.

:::{literalinclude} implement/lib/impl/impl.ml
:language: ocaml
:::


## Conclusion

In this section you have learned to implement a parameter. We have added the
following files:

::::{dropdown} `lib/impl/dune`
:icon: file-code

:::{literalinclude} implement/lib/impl/dune
:language: dune
:::
::::

::::{dropdown} `lib/impl/impl.ml`
:icon: file-code

:::{literalinclude} implement/lib/impl/impl.ml
:language: ocaml
:::
::::

::::{dropdown} `lib/impl/impl.mli`
:icon: file-code

:::{literalinclude} implement/lib/impl/impl.mli
:language: ocaml
:::
::::

You should also have the previous files:

::::{dropdown} `dune-project`
:icon: file-code

:::{literalinclude} implement/dune-project
:language: dune
:::
::::

::::{dropdown} `test/dune`
:icon: file-code

:::{literalinclude} implement/test/dune
:language: dune
:::
::::

::::

::::{dropdown} `test/simple.t`
:icon: file-code

:::{literalinclude} implement/test/simple.t
:language: dune
:::
::::

::::{dropdown} `lib/param/dune`
:icon: file-code

:::{literalinclude} implement/lib/param/dune
:language: dune
:::
::::

::::{dropdown} `lib/param/param.mli`
:icon: file-code

:::{literalinclude} implement/lib/param/param.mli
:language: ocaml
:::
::::

::::

In the next section, we will see how we write a library parameterized by our
parameter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(lang dune 3.20)
(using oxcaml 0.1)

(package (name param))
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(library
(name impl)
(implement param))
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type t = int

let create t = t

let compare = Int.compare
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type t
val create : int -> t
val compare: t -> t -> int
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(library_parameter
(public_name param))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type t
val compare: t -> t -> int
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(cram
(applies_to :whole_subtree)
(enabled_if %{oxcaml_supported}))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This test shows the behavior of the program and ensures it does not have
regression.

$ dune build
38 changes: 38 additions & 0 deletions doc/tutorials/oxcaml-parameterized-library/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
author: Etienne Marais
---

OxCaml Parameterized Library With Dune
======================================

:::{warning}
Parameterized libraries are a feature only supported by the OxCaml branch of
the OCaml compiler. You need to install this version of the compiler to use it
within Dune. This feature should currently be considered as not stable.
:::

This tutorial explains how to create a parameterized library in Dune.
Parameterized library in Dune are a concept similar to
{doc}`/virtual-libraries`. Parameterized libraries are the formalization within
the compiler of virtual libraries.A parameterized library is conceptually
equivalent to a functor. For more detailled explanation, see (TODO @maiste:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it meant to link some documentation about parameterized libraries? Is it available somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 👍🏻

link to explanation).

By the end of the tutorial, you will know:
- how to create a library parameter,
- how to implement a library parameter,
- how to parameterize a library with a library parameter,
- how to instantiate a parameterized library with a a parameter implementation.

To get started make sure you have [oxcaml](https://oxcaml.org/) available in
your path and let's {doc}`setup` our project.

:::{toctree}
:hidden:
:maxdepth: 1
setup
parameter
implement
parameterized_by
instantiate
:::
3 changes: 3 additions & 0 deletions doc/tutorials/oxcaml-parameterized-library/instantiate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Instantiate a Parameterized Library

TODO @maiste: instantiate the parameterized library with the implementation.
101 changes: 101 additions & 0 deletions doc/tutorials/oxcaml-parameterized-library/parameter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Create a Library Parameter

In this section, we are going to learn how to write a
{doc}`/reference/dune/library_parameter`

## Declaring a parameter

We can either declare our parameter as private or public in Dune. In our case,
we are going to declare it as a public parameter. Indeed, Dune doesn't build
unecessary targets. It means it won't build anything that is not needed. In our
case, it would mean our parameter wouldn't get built until we use it. Making it
public informs Dune it is mandatory to build the target.

To build our parameter we are going to use the
{doc}`/reference/dune/library_parameter` stanza.

First, we need to create the directory where we are going to host our
parameter. At the root of our project, we create a `lib/` directory where we
are going to host the code. Inside the `lib/` directory, we create a `param/`
directory to host our parameter. We do this in a single command to save
instructions.

```{code-block} shell
mkdir -p lib/param
```

In `lib/param/`, we create a new `dune` file:

:::{literalinclude} parameter/lib/param/dune
:language: dune
:::
::::

The `library_parameter` stanza takes care of the parameter generation under the
hood. It calls the OxCaml compiler with the correct compiler options and flags.

Still in `lib/param/`, we create the interface for our future libraries in `param.mli`:

:::{literalinclude} parameter/lib/param/param.mli
:language: ocaml
:::
::::

This interface is what our implementation library will need to provide and the
interface of our future parameterized library.

## Conclusion

We have learned how to declare a parameter using Dune with its interface.

Your directory should now contains two additional files:

::::{dropdown} `lib/param/dune`
:icon: file-code

:::{literalinclude} parameter/lib/param/dune
:language: dune
:::
::::

::::{dropdown} `lib/param/param.mli`
:icon: file-code

:::{literalinclude} parameter/lib/param/param.mli
:language: ocaml
:::
::::

::::

The file from the previous should be in the following state:

::::{dropdown} `dune-project`
:icon: file-code

:::{literalinclude} parameter/dune-project
:language: dune
:::
::::

::::{dropdown} `test/dune`
:icon: file-code

:::{literalinclude} parameter/test/dune
:language: dune
:::
::::

::::

::::{dropdown} `test/simple.t`
:icon: file-code

:::{literalinclude} parameter/test/simple.t
:language: dune
:::
::::

In the next part, we are going to learn how to write the implementation of our
parameter.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(lang dune 3.20)
(using oxcaml 0.1)

(package (name param))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(library_parameter
(public_name param))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type t
val compare: t -> t -> int
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(cram
(applies_to :whole_subtree)
(enabled_if %{oxcaml_supported}))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This test shows the behavior of the program and ensures it does not have
regression.

$ dune build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Parameterized a Library

TODO @maiste: Create a library using the parameter.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val foo : string
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(library_parameter (public_name param.a) (name a))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val bar : string
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(library_parameter (name b))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(library (name parameterised) (parameters param.a b))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let test () = print_endline A.foo
Loading
Loading