I am an example in a book, the list was implemented in an imperative style. The itl function mutates the list, i.e. Modifies the list by deleting the first item. After calling itl first element essentially went away forever.
The tricky part is the order in which the icons arguments are executed in the statement:
else icons (f (ihd l)) (imap f (itl l))
The OCaml specification does not specify the order. The last time I checked the INRIA compiler, I ordered the last argument first, so (imap f (itl l)) is executed before (f (ihd l)) . This means that by the time ihd actually called, itl was called enough times to remove all elements of l .
As an example, consider the penultimate recursive call - l is just ["three"] . You think this will result in:
icons (f "three") (imap f [])
However, let's see what happens if you first call itl :
(* l = ["three"] *) let tail = (itl l) in (* tail = [], l = [] *) let head = (ihd l) in (* l = [], ihd raises an exception *) icons head (imap f tail)
As an example, try running this code:
let fxyz = x + y + z f (print_int 1; 1) (print_int 2; 2) (print_int 3; 3)
On my machine (OCaml 3.12) I get this output:
321- : int = 6
source share