请学习如何缩进和空白Lisp中使用,并在新行的帮助和他们没有。
(defun remov (l)
(defparameter z())
(setq contor 0)
(setq counter 0)
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
((push elem z) (setq contor (+ 1 contor)))
(setq counter (+ 1 counter))))
(print e))
眼前的问题:if
有三个参数,评估第一,然后计算并返回第二或第三位。第二种形式是:
((push elem z) (setq contor (+ 1 contor)))
的评价形式的第一个元素是运营商,这是一个函数或特殊的运算符,或λ表达的任一名称。拉姆达表达式的形式如(lambda (x) ...)
。这里,(push elem z)
不符合该描述。那是你得到的错误。
你的意图似乎是要做两件事,一个接一个。这通常在progn
表单中完成。
(progn
(push elem z)
(setq contor (+ 1 contor)))
这产生了:
(defun remov (l)
(defparameter z())
(setq contor 0)
(setq counter 0)
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
(progn
(push elem z)
(setq contor (+ 1 contor)))
(setq counter (+ 1 counter))))
(print e))
现在,defparameter
。这使得z
a 全局特殊变量。在您至少调用一次此功能后,您的整个程序中的任何地方都可以使用z
特殊。这不是你想要的。看来你只是想建立一个新的本地绑定。为此,请使用let
。
(defun remov (l)
(let ((z()))
(setq contor 0)
(setq counter 0)
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
(progn
(push elem z)
(setq contor (+ 1 contor)))
(setq counter (+ 1 counter))))
(print e)))
然后,你有两个setq
表格。除非您在示出的代码之外创建了contor
和counter
的绑定,否则此代码具有未定义的行为(“可能发生任何事情”)。 Setq
不建立新的绑定。看起来你只是想建立新的本地绑定,就像z
一样。使用let
表单。
(defun remov (l)
(let ((z())
(contor 0)
(counter 0))
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
(progn
(push elem z)
(setq contor (+ 1 contor)))
(setq counter (+ 1 counter))))
(print e)))
现在let
建立了z
,contor
和counter
本地绑定。
最后一个错误:e
没有绑定在显示的代码中。我不知道你想在这里做什么,但我认为你只是想在你付出这样的痛苦创造它之后返回z
。由于您将l
和push
循环到z
,z
与l
的对应值相比具有相反的顺序。这个成语,如果你想要有相同的顺序,最后使用nreverse
。函数返回最后一个表单的值。
(defun remov (l)
(let ((z())
(contor 0)
(counter 0))
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
(progn
(push elem z)
(setq contor (+ 1 contor)))
(setq counter (+ 1 counter))))
(nreverse z)))
现在,让我们简化一下。以setq
一个变量为1+
其值,使用宏incf
。 (Incf foo)
扩大到像(setq foo (1+ foo))
。
(defun remov (l)
(let ((z())
(contor 0)
(counter 0))
(dolist (elem l)
(if (or (< (expt 2 contor) counter)
(> (expt 2 contor) counter))
(progn
(push elem z)
(incf contor))
(incf counter)))
(nreverse z)))
如果一个整数a
比任何东西或>
<
,它是/=
。
(defun remov (l)
(let ((z())
(contor 0)
(counter 0))
(dolist (elem l)
(if (/= (expt 2 contor) counter)
(progn
(push elem z)
(incf contor))
(incf counter)))
(nreverse z)))
我倾向于避免名称缩写。
(defun remove-when-foo (list)
(let ((result())
(contor 0)
(counter 0))
(dolist (element list)
(if (/= (expt 2 contor) counter)
(progn
(push element result)
(incf contor))
(incf counter)))
(nreverse z)))
我对此感到逻辑有点惊讶,因为对于if
形式的条件总是在这个循环是真实的。这就是我将其命名为remove-when-foo
的原因。我想这是纠正这是你的下一个努力。
'(push elem z)'之前有一个额外的圆括号。 – Barmar
我不是在你之前的问题中告诉你,你不应该在函数中放置'defparameter'? – Barmar
[LISP“错误非法函数对象...”的可能重复](http://stackoverflow.com/questions/13213605/lisp-error-illegal-function-object) –