>> Would this tail recursive form be more common in practice?
>
> I'm not experienced enough to accurately answer but I prefer the former
> that suppresses one parameter.
Actually that (eta reduction, IIRC) is a dangerous practice in impure
languages like OCaml because it changes when the expressions are evaluated.
In this case, eta reducing by removing the "x" arguments from both sides of
the definition causes the function to partially evaluate sooner, yielding a
closure that encapsulates "n" nested function applications. If you remove
all arguments that were otherwise deferring the evaluation then you can even
change the type of the expression from polymorphic to monomorphic, where the
non-generalized type variable (e.g. '_a) will be ossified at first use or
even resulting in a type error if it tries to escape a compilation unit.
There is also the danger of altering the meaning of the program.
Consider this:
let rec eval state = function
| Int n -> n
| Add(f, g) -> eval state f + eval state g
You might factor out the common "eval state" subexpression:
let rec eval state expr =
let eval = eval state in
match expr with
| Int n -> n
| Add(f, g) -> eval f + eval g
Then you might be tempted to revert back to using "function" to avoid the
superfluous "expr" argument that was not needed before:
let rec eval state =
let eval = eval state in
function
| Int n -> n
| Add(f, g) -> eval f + eval g
But you have now created an infinite loop with "eval state" recursing
indefinitely!
Specifying all arguments in a definition is generally safer and more
efficient in OCaml.
Cheers,
Jon.
.