Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OCaml, why is there an auxiliary function in Core's List.find?

Tags:

list

ocaml

In Core, List.find is defined using an auxiliary function, as follows:

let find l ~f =
  let rec find_aux = function
    | []       -> None
    | hd :: tl -> if f hd then Some hd else find_aux tl
  in
  find_aux l

But it can be defined directly. For instance:

let rec find l ~f =
  match l with
  | []       -> None
  | hd :: tl -> if f hd then Some hd else find tl f

Is there any advantage in using an auxiliary function for defining a function such as List.find?

like image 549
jpvillaisaza Avatar asked Jul 24 '14 21:07

jpvillaisaza


1 Answers

In this case, it doesn't change much because both functions are tail-recursive, but still, the answer to your question is:

calling find requires passing two arguments. Calling find_aux requires passing one argument. Passing arguments is not free: they take up space on the stack, limiting the maximum recursion depth if the function is not tail-recursive, and they take time to set up.

It is a trade-off: in Core's version, a closure must be allocated to bind the name f to its (locally) permanent value. If the list is short, allocating the closure can be more expensive than passing a few additional arguments (esp. since the function is tail-recursive).

Basically, you shouldn't worry about it. It is probably unnecessary in this case, and even when it is not unnecessary, it does not make a big difference.

like image 129
Pascal Cuoq Avatar answered Sep 17 '22 00:09

Pascal Cuoq