【问题标题】:#1# is not a symbol or lambda expression#1# 不是符号或 lambda 表达式
【发布时间】:2018-05-29 13:03:13
【问题描述】:

我尝试在 LISP 中创建 Euklid 算法。 我的代码:

(defun euklid( x y)
   (cond
     ((= x y) x)
     ((> x y) (euklid((- x y) y)))
     )

我收到一个错误In the form (#1=(- X Y) Y), #1# is not a symbol or lambda expression. 我怎样才能纠正这个错误?我知道我的代码中有错误。

【问题讨论】:

  • 调用EUKLID时,参数周围有额外的括号
  • @jkiiski,谢谢!
  • 您将*print-circle* 变量设置为true(否则调试器在准备错误消息时会这样做)。这就是为什么神秘的错误信息。如果*print-circle*nil,则错误消息将类似于“在 ((-X Y) Y) 的形式中,(-X Y) 不是符号或 lambda 表达式”。这就是它的意思。 #1= 的意思是“在标签 1 下注册下面的对象”,然后#1# 的意思是“引用之前标记为 1 的对象”。通过这种“循环符号”,Lisp 支持在打印中准确呈现循环结构和 DAG。
  • @Kaz 很好的解释,虽然我认为“结构共享表示法”(而不是“圆形表示法”)更清晰一些。

标签: lisp common-lisp


【解决方案1】:

阅读器变量

#1=... 语法 (sharpsign-equal) 意味着您的 Lisp 环境正在将 ... 表示的任何数据绑定到读取器变量号 1。#1# 语法 (sharpsign-sharpsign) 引用的数据是以前绑定到同一个读取器变量。

因此,您的 Lisp 环境表明 (- X Y) 形式不是符号或 lambda 表达式,而是通过使用指向函数内部错误子表达式的读取器变量来实现。

不是符号或 lambda 表达式

在正常的评估规则下(没有特殊运算符,没有宏的一部分),像(f x y ...) 这样的列表是一个函数调用,其中f 是被调用的函数,xy、...论据。唯一可以显示为f 的可能值是符号,如(mod 10 3),或文字lambda 表达式,如((lambda (x y) (mod x y)) 10 3)。如果您需要在运行时确定正在调用哪些函数,请使用funcall(例如(funcall (alexandria:compose #'/ #'+) 10 20))。

在这里您输入了(- X Y),它既不是符号也不是 lambda 表达式。 你需要改写:

(euklid (- X Y) Y)

【讨论】:

    【解决方案2】:

    在您的函数公式中,您忘记了一个重要事实,即在您的代码中输入的顺序是相关的。

    此代码使输入的顺序无关紧要:

    ;; correct version:
    
    (defun euklid (x y)
      (let ((x (max x y))
            (y (min x y)))
        (cond
          ((= x y) x)
          ((> x y) (euklid (- x y) y)))))
    

    首先我更正:

    (defun euklid (x y)
       (cond
         ((= x y) x)
         ((> x y) (euklid (- x y) y))))
    

    但我意识到输入的顺序与此功能有关:

    (euklid 3 9)
    ;; returns NIL!
    
    (euklid 9 3)
    ;; returns 3
    

    min / max 绑定到yx,分别使您的输入顺序无关紧要,我认为这是人们希望从euklid 之类的函数中获得的一种行为,不是是吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-31
      • 2014-03-24
      • 2023-03-15
      • 2021-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多