Lisp dolist中的推送错误 (拆卸(l) (def参数z()) (setq contor 0) (setq计数器0) (图1) (如果 (或((出口2 contor)计数器)) ((推送元件z)(setq contor(+1 contor)))(setq计数器(+1计数器))) ) (打印e) )

Lisp dolist中的推送错误 (拆卸(l) (def参数z()) (setq contor 0) (setq计数器0) (图1) (如果 (或((出口2 contor)计数器)) ((推送元件z)(setq contor(+1 contor)))(setq计数器(+1计数器))) ) (打印e) ),lisp,Lisp,为什么我得到错误:非法函数对象:(PUSH ELEM Z)。 [条件类型:类型错误]? 这意味着什么?如果要将多个表达式作为一个块执行,则必须使用progn,不能将它们包装在列表中。列表的第一个元素应该是要调用的函数,(push elem z)不是有效的函数 (defun remov(l) (defparameter z ()) (setq contor 0) (setq counter 0) (dolist (elem l) (if (or (<

为什么我得到
错误:非法函数对象:(PUSH ELEM Z)。
[条件类型:类型错误]

这意味着什么?

如果要将多个表达式作为一个块执行,则必须使用
progn
,不能将它们包装在列表中。列表的第一个元素应该是要调用的函数,
(push elem z)
不是有效的函数

(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)
  )
(如果
(或(<(出口2 contor)计数器)(>(出口2 contor)计数器))
(项目
(推动elem z)
(setq contor(+1 contor)))
(setq计数器(+1个计数器)))
)

如果要将多个表达式作为一个块执行,则必须使用
progn
,不能将它们包装在列表中。列表的第一个元素应该是要调用的函数,
(push elem z)
不是有效的函数

(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)
  )
(如果
(或(<(出口2 contor)计数器)(>(出口2 contor)计数器))
(项目
(推动elem z)
(setq contor(+1 contor)))
(setq计数器(+1个计数器)))
)

请了解缩进和空格在Lisp中是如何使用的,以及新行在哪里有用,在哪里不有用

(if
    (or (< (expt 2 contor) counter) (> (expt 2 contor) counter)) 
    (progn
      (push elem z)
      (setq contor (+ 1 contor)))
    (setq counter (+ 1 counter)))
)
求值形式的第一个元素是运算符,它是函数或特殊运算符的名称,或者是lambda表达式。lambda表达式的形式类似于
(lambda(x)…
。此处,
(按elem z)
不符合该描述。这就是你得到的错误

你的意图似乎是做两件事,一件接一件。这通常以
progn
的形式完成

((push elem z) (setq contor (+ 1 contor)))
(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)))
这将产生:

(progn
  (push elem z)
  (setq contor (+ 1 contor)))
然后,您有两个
setq
表单。除非您在显示的代码之外创建了
contor
counter
的绑定,否则此代码具有未定义的行为(“可能发生任何事情”)
Setq
不建立新绑定。似乎您只想建立新的本地绑定,就像使用
z
一样。使用
let
表单

((push elem z) (setq contor (+ 1 contor)))
(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)))
现在,让我们简化一下。要将变量设置为
1+
其值,请使用宏
incf
(Incf foo)
扩展为类似于
(setq foo(1+foo))

我倾向于避免名字的缩写

(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)))

我对这种逻辑感到有点惊讶,因为在这个循环中,
if
形式的条件总是正确的。这就是为什么我将它命名为
remove when foo
。我想纠正这一点是你下一步的努力。

请了解缩进和空格在Lisp中是如何使用的,新行在哪里有用,在哪里没有

(if
    (or (< (expt 2 contor) counter) (> (expt 2 contor) counter)) 
    (progn
      (push elem z)
      (setq contor (+ 1 contor)))
    (setq counter (+ 1 counter)))
)
求值形式的第一个元素是运算符,它是函数或特殊运算符的名称,或者是lambda表达式。lambda表达式的形式类似于
(lambda(x)…
。此处,
(按elem z)
不符合该描述。这就是你得到的错误

你的意图似乎是做两件事,一件接一件。这通常以
progn
的形式完成

((push elem z) (setq contor (+ 1 contor)))
(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)))
这将产生:

(progn
  (push elem z)
  (setq contor (+ 1 contor)))
然后,您有两个
setq
表单。除非您在显示的代码之外创建了
contor
counter
的绑定,否则此代码具有未定义的行为(“可能发生任何事情”)
Setq
不建立新绑定。似乎您只想建立新的本地绑定,就像使用
z
一样。使用
let
表单

((push elem z) (setq contor (+ 1 contor)))
(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)))
现在,让我们简化一下。要将变量设置为
1+
其值,请使用宏
incf
(Incf foo)
扩展为类似于
(setq foo(1+foo))

我倾向于避免名字的缩写

(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)))

我对这种逻辑感到有点惊讶,因为在这个循环中,
if
形式的条件总是正确的。这就是为什么我将它命名为
remove when foo
。我想纠正这一点是你下一步的努力。

你在
(push elem z)
之前有一组额外的括号。我不是在你之前的问题中告诉过你,你不应该把
defparameter
放在函数中吗?可能的重复看起来像是你在尝试用Lisp编写C代码。如果您停止这样做,转而学习Lisp,您可能会获得更大的成功。在
(push elem z)
之前有一组额外的括号。我不是在您前面的问题中告诉过您不应该将
defparameter
放在函数中吗?可能的重复看起来像您正在尝试用Lisp编写C代码。如果你停止这样做,转而学习Lisp,你可能会取得更大的成功。回答得很好!如果我能多次投票,我会的。回答得很好!如果我能多次投票,我会的。