Very simply put (I am really sorry if this is a naive question): why are some functions of the `Queue`

module (standard library), namely `copy`

, `iter`

, and `fold`

implemented using a pattern

```
let f =
let rec f ...
in
fun q ...
```

?

To give a concrete example, the `iter`

function is implemented as follows:

```
let iter =
let rec iter f cell =
match cell with
| Nil -> ()
| Cons { content; next } ->
f content;
iter f next
in
fun f q -> iter f q.first
```

Is there any memory or allocation trick behind these choices of implementations? In the case of `iter`

what would be the difference with having

```
let iter f q =
let rec iter f cell =
match cell with
| Nil -> ()
| Cons { content; next } ->
f content;
iter f next
in
iter f q.first
```

The difference is that without optimisation, the second version allocates one closure for the inner `iter`

function everytime the outer `iter`

function is called.

With the native compiler the second version will be optimised into the first one anyway, but in bytecode you should be able to notice the extra allocation.

3 Likes

Ahh, interesting It makes perfect sense, thank you so much for your answer!

I wounder, why can’t we find this pattern among other mother in the Standard Library? Is it the fact that `Queue`

allocates more memory (given the representation of the data structure), hence we need to gain a little bit more somewhere else?

I suspect that it’s the only Stdlib module to have a recursive type wrapped in an outer record.

This means that one needs to write auxiliary recursive functions to traverse the inner structure, that do not need to be exported. In the other modules, I expect that the functions that are exported can be defined directly at toplevel, so no need for the inner function.

Have you seen other modules with the pattern `let f x y = let rec f a b = ... in f x y`

or similar ? If so, you can propose to switch to the better pattern with `fun x y -> f x y`

at the end, although I’m not sure it’s worth the trouble.