Will OCaml compiler deal with boolean operators to make recursion tail-recursive? -
let's have @ following function is_prime:
let is_prime n = let rec div_check = * > n || (n mod <> 0 && div_check (i+1)) in n >= 2 && div_check 2 so if n mod <> 0 false, stop.
but if n mod <> 0 true, recursively continue.
my question if continues, has ocaml optimised compiler return div_check(i+1) directly, i.e., tail-recursive? or still hold true && part , wait div_check return?
ps function taken http://www.cs.cornell.edu/courses/cs3110/2014sp/lectures/2/lec02.html
the answer yes. i've simplified example, make compiler output more understandable:
let rec is_prime n = let rec div_check = * > n || (i + < n && div_check (i+1)) in div_check n given input, compiler emit following assembly (i've added annotations):
camlis_prime__div_check_1010: .l102: movq 16(%rbx), %rdi movq %rax, %rsi sarq $1, %rsi movq %rax, %rdx decq %rdx imulq %rsi, %rdx ; * incq %rdx cmpq %rdi, %rdx ; if * <= n return jle .l101 movq $3, %rax ret .l101: movq 16(%rbx), %rdi leaq -1(%rax, %rax), %rsi ; + cmpq %rdi, %rsi ; + ? n jge .l100 ; if + >= n return addq $2, %rax ; else := + 1 jmp .l102 ; div_check .l100: movq $1, %rax ret but cautious, work vanilla ocaml's short-circuit operators. such harmless change as, let (&&) = (&&) break it, , jmp .l102, substituted call camlis_prime__div_check_....
also, work if call right of short-circuit operator. left expression marked non tail-recursive. i've tested and, indeed, putting div_check left of && operator emit non tail-recursive code.
if you're in doubt whether call tail or not, can add -annot flag compiler, , @ corresponding *.annot file, call (tail) annotations. there tooling support in merlin that, i've not figured out on how use properly. , keep in mind, final judge still assembly output.
Comments
Post a Comment