> Hmm, it seems that I begin to detect some advantages in tco/tc :) > > For example, in pil64 I had a function calculating the digits of pi ad > infinitum: > > # Print next digit of PI > (de piDigit () > (job '((Q . 1) (R . 0) (S . 1) (K . 1) (N . 3) (L . 3)) > (while (>= (- (+ R (* 4 Q)) S) (* N S)) > (mapc set '(Q R S K N L) > (list > (* Q K) > (* L (+ R (* 2 Q))) > (* S L) > (inc K) > (/ (+ (* Q (+ 2 (* 7 K))) (* R L)) (* S L)) > (+ 2 L) ) ) ) > (setq > Q (* 10 Q) > R (* 10 (- R (* N S))) ) > (swap 'N M) ) ) > > # Print all digits of PI > (prin (piDigit) ".") > (loop > (prin (piDigit)) > (flush) ) > > We see, it has a 'while' loop using 'set' and 'list' to get an atomic > assignment of the six variables. > > > Now, here tco/tc come in handy, as it *is* a loop with atomic > assignment! :) > > # Print next digit of PI > (de piDigit () > (job '((Q . 1) (R . 0) (S . 1) (K . 1) (N . 3) (L . 3)) > (tco (Q R S K N L) > (if (>= (- (+ R (* 4 Q)) S) (* N S)) > (tc > (* Q K) > (* L (+ R (* 2 Q))) > (* S L) > (inc K) > (/ (+ (* Q (+ 2 (* 7 K))) (* R L)) (* S L)) > (+ 2 L) ) > (setq > Q (* 10 Q) > R (* 10 (- R (* N S))) ) > (swap 'N M) ) ) ) ) > > # Print all digits of PI > (prin (piDigit) ".") > (loop > (prin (piDigit)) > (flush) )
Very cool! Comparing the two functions is worth a bit of study. The tco version does look a lot cleaner. The application of mapc for assignment in the first function is very neat. I had not thought of that use. Question: Without fully understanding the algorithm, it seems N is the next digit to return... But why write that as (swap 'N M)? M is NIL if not defined but otherwise may have some other random value which, if set, does cause results to go astray. Thanks for sharing this code. /Lindsay