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
?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With