.. meta:: :description lang=en: List.iteri and Array.iteri in OCaml :description lang=fr: List.iteri et Array.iteri en OCaml #################################### List.iteri and Array.iteri in OCaml #################################### .. note:: This is a small article about two very convenient function in the `OCaml language `_. .. warning:: 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* [#listiter]_ and *Array* [#arrayiter]_. These functions are iterators of the following type: .. code-block:: ocaml 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: .. code-block:: ocaml 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. : .. code-block:: python 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 [#arraydiff]_, but its straightforward equivalent for lists *List.iteri* has only been added **in… 2010** with OCaml v4.00.1 ! (cf [#listdiff]_). 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 [#projet]_. In particular, this link [#patch]_ 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. ------------------------------------------------------------------------------ .. rubric:: References .. [#arrayiter] :Documentation: `Array.iter `_ in the doc of the Array module; .. [#listiter] :Documentation: `List.iter `_ in the doc of the List module; .. [#arraydiff] :Source: the `diff on array.ml `_ which introduced the *Array.iteri* function (on the INRIA's *svn* repository); .. [#listdiff] :Source: the `diff on list.ml `_ which introduced the *List.iteri* function (on the INRIA's *svn* repository); .. [#projet] :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"); .. [#patch] :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! .. (c) Lilian Besson, 2016, https://bitbucket.org/lbesson/web-sphinx/