# Are there any OCaml's best practices?

**URL:** https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583
**Category:** Learning
**Tags:** ocaml, best-practices
**Created:** [February 16, 2018, 4:46pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583 "2018-02-16T16:46:28Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![egoholic](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/egoholic/32/574_2.png) [@egoholic](https://discuss.ocaml.org/u/egoholic)
#### Post date: [February 16, 2018, 4:46pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/1 "2018-02-16T16:46:28Z")

</div>

Is there any OCaml’s best practices? What materials can help me to improve my OCaml code?

---

<div class="post-metadata">

### Author: ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)
#### Post date: [February 16, 2018, 5:23pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/2 "2018-02-16T17:23:17Z")

</div>

A little biased, but these might be of use:

[https://realworldocaml.org](https://realworldocaml.org)  
[https://dev.realworldocaml.org/](https://dev.realworldocaml.org/) (in active development, but more up-to-date)

---

<div class="post-metadata">

### Author: ![theindigamer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/theindigamer/32/610_2.png) [@theindigamer](https://discuss.ocaml.org/u/theindigamer)
#### Post date: [February 16, 2018, 9:55pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/3 "2018-02-16T21:55:51Z")

</div>

There are many good practices that are general to functional languages, not specific to OCaml. ~~For example, having the key data structure as the last argument is very useful when chaining calls.~~ [see yminsky’s reply] Using abstract types when possible is also a good idea. This point is documented in the [Elm design guidelines](http://package.elm-lang.org/help/design-guidelines#the-data-structure-is-always-the-last-argument) but it is equally applicable to OCaml.

Of course, some communities (or even members in the same community) may not agree on a point - e.g. having custom infix operators (how many are too many?).

---

<div class="post-metadata">

### Author: ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)
#### Post date: [February 17, 2018, 5:08am UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/4 "2018-02-17T05:08:29Z")

</div>

> [@theindigamer](#):
>
> There are many good practices that are general to functional languages, not specific to OCaml. For example, having the key data structure as the last argument is very useful when chaining calls. Using abstract types when possible is also a good idea. Both of these points are documented in the [Elm design guidelines](http://package.elm-lang.org/help/design-guidelines#the-data-structure-is-always-the-last-argument) but they’re equally applicable to OCaml.

This one’s not especially widely agreed upon. The Base/Core guidelines specify putting the primary element as the first argument, though the use of labeled arguments provides some flexibility on argument order.

---

<div class="post-metadata">

### Author: ![andreypopp](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/andreypopp/32/97_2.png) [@andreypopp](https://discuss.ocaml.org/u/andreypopp)
#### Post date: [February 17, 2018, 7:25am UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/5 "2018-02-17T07:25:00Z")

</div>

> [@Yaron\_Minsky](#):
>
> The Base/Core guidelines specify putting the primary element as the first argument, though the use of labeled arguments provides some flexibility on argument order.

Is there a place I can read Base/Core design guidelines?

---

<div class="post-metadata">

### Author: ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)
#### Post date: [February 17, 2018, 2:29pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/6 "2018-02-17T14:29:22Z")

</div>

This chapter describes some of the major components:

[https://dev.realworldocaml.org/04-files-modules-and-programs.html](https://dev.realworldocaml.org/04-files-modules-and-programs.html)

in the section “Designing with Modules”, and in particular in the “Create Uniform Interfaces” part.

We do have a more detailed internal style guide, but that’s not currently public.

---

<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: [February 17, 2018, 6:30pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/7 "2018-02-17T18:30:11Z")

</div>

I have a limited style guide [OCaml Towards Clarity and Grace](https://github.com/lindig/ocaml-style/) that includes references to others style guides. I am happy to include additions and critical discussions.

A style guide can help to become aware of some OCaml issues but there is a whole range of knowledge that could improve your code that is not covered by the topic of style: knowing more about clever functional algorithms or advanced usage of the type system. The books mentioned by others are a good start.

---

<div class="post-metadata">

### Author: ![theindigamer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/theindigamer/32/610_2.png) [@theindigamer](https://discuss.ocaml.org/u/theindigamer)
#### Post date: [February 17, 2018, 11:13pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/8 "2018-02-17T23:13:52Z")

</div>

Good point, I stand corrected then. Although I’m curious why the Base/Core guidelines make the suggestion that they do. There doesn’t seem to be any reasoning provided there (or am I just not looking carefully enough?). It would be useful if, beneath each point in the guideline, the rationale behind it were written down. That way a project can “opt in” to guidelines after determining what points are applicable to their code base.

---

<div class="post-metadata">

### Author: ![ShalokShalom](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shalokshalom/32/419_2.png) [@ShalokShalom](https://discuss.ocaml.org/u/ShalokShalom)
#### Post date: [February 20, 2018, 2:28am UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/9 "2018-02-20T02:28:39Z")

</div>

Did you report this issue?

---

<div class="post-metadata">

### Author: ![basus](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/basus/32/29_2.png) [@basus](https://discuss.ocaml.org/u/basus)
#### Post date: [February 20, 2018, 6:48pm UTC](https://discuss.ocaml.org/t/are-there-any-ocamls-best-practices/1583/10 "2018-02-20T18:48:56Z")

</div>

> Although I’m curious why the Base/Core guidelines make the suggestion that they do. There doesn’t seem to be any reasoning provided there (or am I just not looking carefully enough?).

Having the main type be first argument, with heavy use of named parameters, lets us write calls in the same way as having it be the last argument. If we have a bunch of operations on some `type t`, we can chain them together in two ways. Assuming that the API is written with the `t` parameter being last, we can write:

```auto
let t' = op1 t |>
         op2 arg |>
         op3 arg1 arg2

```

Now, in the Base/Core style, `op2` and `op3` would take `t` as the first parameter, and the rest would be named. So we could write:

```auto
let t' = op1 t |>
         op2 ~param1:arg1 |>
         op3 ~param1:arg1 ~param2:arg2

```

If we didn’t use either style, we’d need to use some intermediate bindings to store and pass along the results of the different `op`s, or use a function like `flip` to effectively move around the order of arguments (which would not work in all cases).

Hope that helps.
