Anonymous user
99 bottles of beer: Difference between revisions
→{{header|TXR}}: Eliminate external utility; use a lazy list instead.
(Add an ATS implementation. My own work.) |
(→{{header|TXR}}: Eliminate external utility; use a lazy list instead.) |
||
Line 4,419:
=={{header|TXR}}==
Previously, this used an external command to generate a text stream of numbers from 99 to -1, one per line. For fun, this is now replaced by a lazy list, keeping the rest of the program intact: processes a stream of numbers and transforms then into the song. Lazy lists are based on lazy conses. A lazy cons is a special object which contains a function. When the object is accessed using the usual cons accessors, the function is called to fill in the car and cdr slots of the object. To terminate the list, the function writes a nil into the cdr. If the list is to be continued, the function can put a continuation tail into cdr, which can be a concrete list, or another lazy cons (which can re-use the same lazy cons function, using the trick shown in this example).
<lang txr>@(do (defun lazy-textual-number-list (min max)
(let ((counter min)
(delta (if (<= min max) 1 -1)))
(make-lazy-cons (lambda (lcons)
(rplaca lcons (format nil "~a" counter))
(cond
((eql counter max)
(rplacd lcons nil) t)
(t
(inc counter delta)
(rplacd lcons (make-lazy-cons
(lcons-fun lcons))))))))))
@(next :list @(lazy-textual-number-list 99 -1))
@(collect)
@number
|