Lisp:如何使用循环命名,然后是 return-from

Lisp: How to use loop named, then return-from

这个 lisp 有效(SBCL 1.2.15):

(defun roman2 ()
    (let ((x nil))
      (loop 
           (cond
             ((null x) (format t "Enter number:") (setf x (read)))
             ((> x 39) (format t "too big~%") (setf x nil))
             ((> x 9) (prin1 'x) (setf x (- x 10)) )
             ((= x 9) (prin1 'ix) (setf x 0) )
             ((> x 4) (prin1 'v) (setf x (- x 5)) )
             ((= x 4) (prin1 'iv) (setf x 0) )
             ((> x 0) (prin1 'i) (setf x (1- x)) )
             ((zerop x) (setf x nil) (terpri))
             ((< x 0) (format t "Bye.") (return))))))

而这不是

(defun roman2 ()
    (let ((x nil))
      (loop named rlp
           (cond
             ((null x) (format t "Enter number:") (setf x (read)))
             ((> x 39) (format t "too big~%") (setf x nil))
             ((> x 9) (prin1 'x) (setf x (- x 10)) )
             ((= x 9) (prin1 'ix) (setf x 0) )
             ((> x 4) (prin1 'v) (setf x (- x 5)) )
             ((= x 4) (prin1 'iv) (setf x 0) )
             ((> x 0) (prin1 'i) (setf x (1- x)) )
             ((zerop x) (setf x nil) (terpri))
             ((< x 0) (format t "Bye.") (return-from rlp))))))

有错误

caught ERROR:
;   during macroexpansion of (LOOP NAMED RLP ...). Use *BREAK-ON-SIGNALS* to
;   intercept.

我不确定我做错了什么。好像如果我已经命名了我的循环,我可以用 (return-from rlp)

来突破

loop有两种形式。第一个只是 (loop forms...),这是您拥有的第一个。第二种要复杂得多,它使用一种用循环关键字构建的复杂语言来描述循环。一旦你使用 named 你就属于后者。试试 (loop named name do (cond ...)).