;;;; bottles6.lsp

;;; Solution using nested function definition and closure
;;;
(defun bottles (X)
 "Song '99 bottles on the wall'"
  (do 
      ((take-one (make-stock X)))
      ((zerop (status)) )
      (funcall take-one)))

(defun make-stock (X)
  (let ((stock X))
    (defun status ()
      (cond ((> stock 1)
	     (format t "~a bottles of beer on the wall. " stock) stock)
	    ((< stock 1) (format t "Now, they are all gone. ") stock)
	    (t (format t "1 bottle of beer on the wall. ") stock)))
    #'(lambda ()
        (progn
          (format t "Take one down, and pass it around.~%")
          (setf stock (- stock 1))))))
