f# - When executed will this be a tail call? -
once compiled , ran behave tail call?
let rec f accu = function | [] -> accu | h::t -> (h + accu) |> f <| t
maybe there easy way test behavior i'm not aware of, might question.
i think easier see if not use pipelining operator. in fact, 2 pipelining operators defined inline
, compiler simplify code following (and think version more readable , simpler understand, write this):
let rec f accu = function | [] -> accu | h::t -> f (h + accu) t
now, can read definition of tail-call on wikipedia, says:
a tail call subroutine call happens inside procedure final action; may produce return value returned calling procedure.
so yes, call f
on last line tail-call.
if wanted analyze original expression (h + accu) |> f <| t
(without knowing pipelining operators inlined), becomes ((h + accu) |> f) <| t
. means expression calls <|
operator 2 arguments , returns result - call <|
tail call.
the <|
operator defined this:
let (<|) f = f
now, call f
inside pipelining operator tail-call (and other pipelining operator).
in summary, if compiler did not inlining, have sequence of 3 tail-calls (compiled using .net .tail
instruction make sure .net performs tail-call). however, since compiler performs inlining, see have recursive tail-call (f
calling f
) , can more efficiently compiled loop. (but calls across multiple functions or operators cannot use loops easily.)
Comments
Post a Comment