List.iteri and Array.iteri in OCaml

Note

This is a small article about two very convenient function in the OCaml language.

Avis

If the name OCaml does not ring a bell for you, this article will probably not interest you at all!

List.iter and Array.iter

These are two very classical functions, from the modules List [2] and Array [1].

These functions are iterators of the following type:

val List.iter : ('a -> unit) -> 'a list -> unit
val Array.iter : ('a -> unit) -> 'a array -> unit

They allow to apply a certain function f : 'a -> unit which acts by side effects (e.g., printing) to each element of a list or an array.

Very convenient!

A better version?

But... quite often, we need more than just the value of x of each element, we might need their index i (for instance to print something like "the ith value contains x[i]").

So, we would like to have two other iterator functions with the following signature:

val List.iteri : (int -> 'a -> unit) -> 'a list -> unit
val Array.iteri : (int -> 'a -> unit) -> 'a array -> unit

Now, f accepts as first argument the index i corresponding to its second argument the value xi. That will be very convenient to avoid for loops!

Note

In Python... ?

The common syntax for every iterator is already doing this, e.g. :

for i in [2*i for i in range(8)]:
    print i

And the enumerate function also allows to iterate on both index and value, i, xi.

Two functions that took their time to appear

We can check that Array.iteri has been implemented back in 1997 [3], but its straightforward equivalent for lists List.iteri has only been added in... 2010 with OCaml v4.00.1 ! (cf [4]).

So what's the issue?

These two functions are very useful, and so they are used a lot.

During some programming projects and exercises that were asked to me during some courses at ENS Cachan, I have been ask to make my OCaml code work on at least a machine in room 411, machines which were old at this time!

And that's why in December 2013, we lost a few minutes (during an oral exam) trying to find the source of a bug, and I included a tiny "patch" v3.12 → v4.01.0 which adds manually the code for List.iteri in my project [5].

In particular, this link [6] shows the different modifications on my code, after I saw this bug.

Anyway, we would have liked to get them before!

That's basically what this (useless) article was about.


References

[1]
Documentation:Array.iter in the doc of the Array module;
[2]
Documentation:List.iter in the doc of the List module;
[3]
Source:the diff on array.ml which introduced the Array.iteri function (on the INRIA's svn repository);
[4]
Source:the diff on list.ml which introduced the List.iteri function (on the INRIA's svn repository);
[5]
Cf.:the written report (in French) for the tiny Laby project implemented in December 2013, as a training for the computer-science oral exam for the highly competitive french national exam to become a prep' school professor ("agrégation");
[6]
Cf.:the commit reporting compatibility with OCaml v3.12.1 for my Laby project (private).

Note

« But OCaml is lame isn't it? »

No, do not listen to people saying this, OCaml is awesome!