pam*_*pam 1 lisp functional-programming common-lisp
(defun take-n (lst i)
(setf newlst '())
(dotimes (n i)
(setf newlst (cons (car lst) newlst))
(print (cons (car lst) newlst))
(setf lst (cdr lst)))
(return newlst))
(print (take-n '(1 2 3) 2))
Run Code Online (Sandbox Code Playgroud)
这给我一个错误RETURN-FROM:当前看不到名为NIL的块。我已经尝试过将return语句移到其他位置,但是我不确定它的含义。
请以Lisp方式缩进代码(可以在许多编辑器(例如Emacs)中自动完成):
(defun take-n (lst i)
(setf newlst '())
(dotimes (n i)
(setf newlst (cons (car lst) newlst))
(print (cons (car lst) newlst))
(setf lst (cdr lst)))
(return newlst))
(print (take-n '(1 2 3) 2))
Run Code Online (Sandbox Code Playgroud)不要使用未setf
事先声明的变量:(setf newlst '())
这里指的是假设的全局变量newlst
,但是在函数中,您应该努力只具有局部状态。使用let
,在块中引入变量,如下所示:
(let ((new-list ()))
...
;; here you can setf new-list if you need
...)
Run Code Online (Sandbox Code Playgroud)(setf newlst (cons (car lst) newlst))
也可以写成(push (car lst) newlst)
,但请不要使用过分缩写的名称;例如,您可以使用list
和new-list
。
return
返回到名为的封闭块nil
,但是这里没有这样的块。相反,defun
引入一个隐式块,其名称类似于您定义的函数,即您已经隐式地:
(block take-n
...)
Run Code Online (Sandbox Code Playgroud)
因此,如果您想从中返回,则需要这样做(return-from take-n newlst)
。
但是,您不需要返回,因为该函数中最后一个要求值的形式还是与该函数调用关联的值。
您无需使用RETURN
。在Lisp中,函数主体中的最后一个表达式是自动返回的,因此只需将变量放在函数的末尾即可。另外,您应将本地变量与绑定LET
,而不要分配全局变量。
(defun take-n (lst i)
(let ((newlist '()))
(dotimes (n i)
(setf newlst (cons (car lst) newlst))
(print (cons (car lst) newlst))
(setf lst (cdr lst)))
newlst))
Run Code Online (Sandbox Code Playgroud)
您得到的错误是因为DEFUN
在函数体周围放置了一个命名块,因此您需要使用(return-from take-n newlst)
。return
只能用于从未命名的块(名称为的块NIL
)返回;这些自动围绕循环宏之类的DO
。