3 ms·
At the assembly/bytecode level, you still have to save the return value of the recursive call and then do something to it, whereas a tail call wouldn't need to
by Hemospectrum 16y ago
At the assembly/bytecode level, you still have to save the return value of the recursive call and then do something to it, whereas a tail call wouldn't need to save any intermediate value because it would immediately return it as soon as it got it.
I guess Java's infix notation kind of obscures this. This is one of the reasons why functional programmers prefer to consider everything a function. It's also why some languages (like Clojure) have special syntax for tail calls, with special error messages if you goof up the semantics.
- Uchikoma 16y agoI like this idea - never came up to me before n * fac(n-1) vs. * n fac(- n 1) or * (n, fac(n-1)) as a method call, which makes it clear * is the last function that's called.
- eru 16y agoYes, in Lisp there's no real difference between * or car. In Haskell, which has more syntax, you can use * in infix notation, but so you can with other function. E.g. the function `on`. Quoting from the documentation: on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (*) `on` f = \x y -> f x * f y. Typical usage: Data.List.sortBy (compare `on` fst).