From: Vittorio Giannini

Subject: On tail-recursion, closures and other newbie questions

Date: 1998-8-26 8:51

Juanma Barranquero writes:
> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > I'm reading the interesting book _On Lisp_, by Paul Graham, where the > author postulates that sometimes it is better and/or more natural to > develop an algorithm like a tail-recursive function (instead of > iterative) and notes that that should incur no penalty because most > implementations are very good at optimizing tail-recursion. Then he > shows some examples in which a non-tail-recursive function can be > translated into one (that hopefully will be optimized by the > compiler). > > So I tried to test it with ACL 5.0.beta for Windows and found a > puzzling (to me, anyway) result. > > Compiling: > > (defun fact-rec (n r) > (declare (optimize (speed 3) (safety 0) (size 3) (debug 0)) > (integer r) > (fixnum n)) > (cond ((<= n 1) r) > (t (fact-rec (1- n) (* n r))))) > > gives a very short (and tail-optimized) 42 bytes subroutine. > > Then I tried to give to that a more user-friendly (fact N) wrapper, > like so: > > (defun fact (num) > (declare (optimize (speed 3) (safety 0) (size 3) (debug 0)) > (fixnum num)) > (labels ((fact-rec (n r) > (declare (fixnum n) > (integer r)) > (cond ((<= n 1) r) > (t (fact-rec (1- n) (* n r)))))) > (fact-rec num 1))) > > where obviously the labels-defined fact-rec is identical to the > subroutine above. And now I get a 80-byte subroutine *plus* another > one (the closure) of 65 bytes. The difference is appaling. Why? > > /L/e/k/t/u > > > -----BEGIN PGP SIGNATURE----- > Version: PGPfreeware 5.5.3i; see <http://www.pgpi.com> > > iQA/AwUBNePh9v4C0a0jUw5YEQIXVACfWuXrdVY4vqnKnCJV21L8uWOTPiQAn1Ie > 4OCUmDqt2KxWX2E2+FNYzVSm > =9zsb > -----END PGP SIGNATURE-----