ocamltail-recursionshort-circuiting

Verify that an OCaml function is tail-recursive


How can I tell if OCaml recognizes a particular function as tail-recursive? In particular, I want to find out if the OCaml compiler recognizes Short-circuited operators and tail recursion


Thanks to Jeffrey's answer below, I tried this with the simple function

let rec check_all l =
    match l with
    | [] -> true
    | hd :: tl ->
        hd && check_all tl

and indeed, it does optimize to:

camlTest__check_all_1008:
        .cfi_startproc
.L102:
        cmpl    $1, %eax
        je      .L100
        movl    (%eax), %ebx
        cmpl    $1, %ebx
        je      .L101
        movl    4(%eax), %eax
        jmp     .L102
        .align  16
.L101:
        movl    $1, %eax
        ret

Solution

  • Starting from OCaml 4.03, and despite the typo in the Changes file, you can use @tailcall in a function application and the compiler will warn if it is not the case.

    (f [@tailcall]) x y warns if f x y is not a tail-call

    Example:

    $ cat tailrec.ml
    let rec f a x = if x <= 1 then a else (f [@tailcall]) (a * x) (x - 1)
    
    let rec g x = if x <= 1 then 1 else x * (g [@tailcall]) (x - 1)
    
    $ ocaml tailrec.ml
    
    File "tailrec.ml", line 3, characters 40-63:
    Warning 51: expected tailcall