I was told in class that the following function is not tail recursive due to the boolean operator being evaluated after the recursive call:
let rec exists p = function
[] -> false
| a::l -> p a || exists p l
But this doesn't blow the stack on a ten-million size list, and what's more, it is the implementation in the standard library. If it weren't tail recursive, there would be no reason to use this form instead of the seemingly equivalent and clearly tail recursive
let rec exists p = function
[] -> false
| a::l -> if p a then true else exists p l
so it seems like the OCaml compiler is capable of optimizing boolean ops in simple cases like this to take advantage of tail recursion. But I noticed that if I switch the order of operands like so
let rec exists p = function
[] -> false
| a::l -> exists p l || p a
then the stack is indeed blown on 10m elements. So it looks like OCaml is only able to take advantage of this when the recursive call appears on the right, which makes me suspect that all the compiler does is replace the boolean op with the equivalent if
expression. Can someone confirm or refute this?