# \[Blog\] 7 OCaml Gotchas

**URL:** <https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667>\
**Category:** Community\
**Tags:** blog\
**Created:** [May 20, 2024, 8:38am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667 "2024-05-20T08:38:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 8:38am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/1 "2024-05-20T08:38:15Z")

</div>

Hi everyone! 👋

I’ve been using OCaml for a while, and I’m quite enjoying the language. In my not-so-long journey, I discovered a few surprising OCaml behaviours, so I decided to share them with everyone in a blog post.

- [7 OCaml Gotchas](https://dev.to/chshersh/7-ocaml-gotchas-207e)

I hope it reduces frustration for newcomers when they see something unexpected for the first time!

---

<div class="post-metadata">

**Author:** ![Fardale](https://avatars.discourse-cdn.com/v4/letter/f/8baadc/32.png) [@Fardale](https://discuss.ocaml.org/u/Fardale)\
**Post date:** [May 20, 2024, 10:04am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/2 "2024-05-20T10:04:52Z")

</div>

Hi!

Thanks for sharing!

I have a two small comments.  
In the 4th section, " Type inference doesn’t work well: Part 1". For record you can use the following syntax: `book.Book.words`. Also note that you need to use it once then you can use `book.title` without the extra `Book`.  
And in the 7th section, if you need to control the order of the argument, the safe way is to do:

```ocaml
let arg1 = expr1 in
let arg2 = expr2 in
f arg1 arg2

```

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [May 20, 2024, 10:09am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/3 "2024-05-20T10:09:05Z")

</div>

Regarding equality functions, you advise to configure your linter to warn on physical equality, but many style guides prefer warning on structural equality instead. The reason is that physical equality has a well-defined meaning on all types (even if it’s not the one you’re expecting), while structural equality is defined in terms of memory representation, and can throw exceptions or loop indefinitely on some inputs. Even when it does terminate, it is not always useful:

```ocaml
# module ISet = Set.Make(Int);;
...
# open ISet;;
# add 0 (add 1 empty) = add 1 (add 0 empty);;
- : bool = false
# equal (add 0 (add 1 empty)) (add 1 (add 0 empty));;
- : bool = true

```

(`equal` here is `ISet.equal`, the set equality function that has the expected semantics)

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 11:23am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/4 "2024-05-20T11:23:49Z")

</div>

> [@Fardale](#):
>
> For record you can use the following syntax: `book.Book.words`. Also note that you need to use it once then you can use `book.title` without the extra `Book`.

I’m aware about this syntax. In fact, my article originally mentioned this approach (and we use it a lot at work). However, I realised that I hate this syntax. So I decided to avoid encouraging syntax I don’t like in my post 😅

> For record you can use the following syntax: `book.Book.words` . Also note that you need to use it once then you can use `book.title` without the extra `Book` .

That’s a good simple solution as well, thanks for mentioning it!

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 11:26am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/5 "2024-05-20T11:26:39Z")

</div>

Indeed, structural equality is not the optimal solution either 😞

You mentioned one reason. Another reason is that it throws an exception when you try to compare functions (so you may suddenly get runtime errors).

I’d recommend using the `equal` function from a structure of choice. Still, I feel like the Haskell solution with the `Eq` typeclass is so far the best solution for a polymorphic well-having equality comparison. I’m trying to cope with the OCaml approach meanwhile 😅

---

<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:** [May 20, 2024, 1:49pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/6 "2024-05-20T13:49:55Z")

</div>

I understand it’s not your personal preference, but somehow doesn’t feel right to hide it from your readers. Let them make their own judgment. Otherwise the article seems to be giving them a skewed view of the language.

---

<div class="post-metadata">

**Author:** ![zoj613](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zoj613/32/5253_2.png) [@zoj613](https://discuss.ocaml.org/u/zoj613)\
**Post date:** [May 20, 2024, 2:07pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/7 "2024-05-20T14:07:41Z")

</div>

Any more practical examples of the 6th gotcha? I have never seen that notation used outside of GADT function definitions.

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 2:24pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/8 "2024-05-20T14:24:21Z")

</div>

I believe it’s fine to provide a personal opinion in an article written on my website 😌

If it was published somewhere on the official OCaml documentation then it should be more objective and less personal.

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 2:28pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/9 "2024-05-20T14:28:09Z")

</div>

I sometimes like to write OCaml functions in Haskell style, where type signature leaves nearby the code.

A few examples:

```ocaml
let unlines : string list -> string = String.concat ~sep:"\n"
let unwords : string list -> string = String.concat ~sep:" "

```

These ones are monomorphic but I can imagine writing polymorphic functions too.

---

<div class="post-metadata">

**Author:** ![zbaylin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zbaylin/32/4047_2.png) [@zbaylin](https://discuss.ocaml.org/u/zbaylin)\
**Post date:** [May 20, 2024, 3:17pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/10 "2024-05-20T15:17:16Z")

</div>

I kind of get what you’re going for with the last one, but I think this may be a holdover from your 8 years of Haskell programming :). Your function/operator:

```auto
let (>>) action1 action2 = action1; action2

```

has type `unit -> 'a -> 'a`, making it essentially just syntactic sugar for `;` (but with the evaluation order inverted). I can imagine you’re expecting `action1` and `action2` to be evaluated within the body of this function but because OCaml is eagerly evaluated, you’re essentially saying

```auto
() >> ()

```

by the time the function is called. The larger point of the RTL evaluation order still stands though.

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 4:10pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/11 "2024-05-20T16:10:31Z")

</div>

Ngl, I found it hard to find real-life examples of where this behaviour can be problematic 😅

Again, after 8 years of Haskell, I don’t rely on order of arguments at all, and prefer to control it explicitly!

Still, I see that many people find this behaviour surprising (myself included). Especially considering that this is different from all mainstream languages. Although, for me it’s not a big problem 😌

---

<div class="post-metadata">

**Author:** ![zbaylin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zbaylin/32/4047_2.png) [@zbaylin](https://discuss.ocaml.org/u/zbaylin)\
**Post date:** [May 20, 2024, 4:37pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/12 "2024-05-20T16:37:48Z")

</div>

Yeah I think that’s a fair assessment – it’s not something that should really ever be an issue unless the two arguments share some mutual mutable state (here that’s `stdout`). I agree that it’s a gotcha but it should be a pretty rare “bug” to encounter in the real world.

---

<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:** [May 20, 2024, 4:42pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/13 "2024-05-20T16:42:34Z")

</div>

The order of evaluation of functions argument is not really right-to-left : it is unspecified which means that different implementations of OCaml could implement whatever order they want. Of course in practice, people ends up relying on the evaluation order by accodent so the compiler will not willy-nilly change the evaluation order for the sake of backward compatibility. However, fundamentally any code that relies on a specific evaluation order of function arguments is bugged.

---

<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:** [May 20, 2024, 4:59pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/14 "2024-05-20T16:59:24Z")

</div>

> [@chshersh](#):
>
> Especially considering that this is different from all mainstream languages.

In C and C++, the evaluation order of arguments (and of sub-expressions) is unspecified. The same is true of scheme. (The latter not a mainstream language but I think C and C++ would count as mainstream.)

---

<div class="post-metadata">

**Author:** ![threepwood](https://avatars.discourse-cdn.com/v4/letter/t/8dc957/32.png) [@threepwood](https://discuss.ocaml.org/u/threepwood)\
**Post date:** [May 20, 2024, 5:43pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/15 "2024-05-20T17:43:03Z")

</div>

I think a more convincing example for the last one would be something like:

```ocaml
let user = find_user (prompt_id ()) (prompt_pwd ()) in ...

```

which will flip the id and the password. Your `(>>)` function just doesn’t make sense, it isn’t doing anything. In general you cannot do anything about the side-effects of computing the arguments from inside a function. If your arguments are genuinely lazy then you control the order of evaluation so there is no gotcha.

---

<div class="post-metadata">

**Author:** ![chshersh](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chshersh/32/4964_2.png) [@chshersh](https://discuss.ocaml.org/u/chshersh)\
**Post date:** [May 20, 2024, 6:43pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/16 "2024-05-20T18:43:05Z")

</div>

This is a good example, thanks for providing it!

---

<div class="post-metadata">

**Author:** ![zoj613](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zoj613/32/5253_2.png) [@zoj613](https://discuss.ocaml.org/u/zoj613)\
**Post date:** [May 20, 2024, 8:55pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/17 "2024-05-20T20:55:13Z")

</div>

I was referring to the `a . a` notation using a dot in the function’s signature

---

<div class="post-metadata">

**Author:** ![yami-no-ryuu](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yami-no-ryuu/32/5315_2.png) [@yami-no-ryuu](https://discuss.ocaml.org/u/yami-no-ryuu)\
**Post date:** [May 21, 2024, 3:23pm UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/18 "2024-05-21T15:23:19Z")

</div>

Book.(book.words) will also work if you want C style

---

<div class="post-metadata">

**Author:** ![Khady](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/khady/32/469_2.png) [@Khady](https://discuss.ocaml.org/u/Khady)\
**Post date:** [May 22, 2024, 1:13am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/19 "2024-05-22T01:13:36Z")

</div>

This is not the same though. This local open might be bringing this `book` value in the environment. So one must be much more careful when using opens vs the `value.Module.field` syntax (what’s the name of this syntax btw?)

---

<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:** [May 22, 2024, 4:40am UTC](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667/20 "2024-05-22T04:40:29Z")

</div>

Based on the manual I don’t see an explicit name for this syntax: [OCaml - The OCaml language](https://ocaml.org/manual/5.2/names.html#field)

From the wording I guess it’s OK to call it a ‘prefixed field name’?

[Next page](https://discuss.ocaml.org/t/blog-7-ocaml-gotchas/14667.md?page=2)
