【问题标题】:Why am I getting this lambda expression error, and what can I do about it?为什么我会收到这个 lambda 表达式错误,我该怎么办?
【发布时间】:2010-09-24 21:17:13
【问题描述】:

我对 lisp 还是很陌生;我想知道这里是否有人可以帮助我。

我有以下代码sn-p:

(defun write-lookup (binding-list pattern fact)
(cond
        ; No bindings have been stored
        ; Return the binding list with a new one!
        ((not binding-list) (cons (cons pattern fact) nil))

        ; A list of bindings is being stored
        (cond

            ; The current binding matches
            ((equal (caar binding-list) pattern)
                ; Return the binding-list if value matches, nil else
                (if (compare pattern fact) binding-list nil))

            ; Recursively search the rest of the list for the binding
            ((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))

            ; The list doesn't have the binding.
            ; Return the binding-list with the added pattern
            ( T (cons (cons pattern fact) binding-list)))))

当我尝试运行它时,我得到以下信息:

*** - SYSTEM::%EXPAND-FORM: (EQUAL (CAAR BINDING-LIST) PATTERN) should be a
  lambda expression

有人可以指出我的错误吗?谢谢!

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    首先你需要正确缩进你的代码:

    (defun write-lookup (binding-list pattern fact)
      (cond
            ; No bindings have been stored
            ; Return the binding list with a new one!
       ((not binding-list) (cons (cons pattern fact) nil))
    
            ; A list of bindings is being stored
       (cond
    
                ; The current binding matches
        ((equal (caar binding-list) pattern)
                    ; Return the binding-list if value matches, nil else
         (if (compare pattern fact) binding-list nil))
    
                ; Recursively search the rest of the list for the binding
        ((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
    
                ; The list doesn't have the binding.
                ; Return the binding-list with the added pattern
        (T (cons (cons pattern fact) binding-list)))))
    

    一个典型的 Lisp 编辑器会在你击键时为你做这件事。

    现在您可以很容易地发现第一个 COND 缺少 T 子句。让我补充一下:

    (defun write-lookup (binding-list pattern fact)
      (cond
            ; No bindings have been stored
            ; Return the binding list with a new one!
       ((not binding-list) (cons (cons pattern fact) nil))
    
            ; A list of bindings is being stored
       (t (cond
    
                ; The current binding matches
           ((equal (caar binding-list) pattern)
                    ; Return the binding-list if value matches, nil else
            (if (compare pattern fact) binding-list nil))
    
                ; Recursively search the rest of the list for the binding
           ((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
    
                ; The list doesn't have the binding.
                ; Return the binding-list with the added pattern
           (T (cons (cons pattern fact) binding-list))))))
    

    我也会将注释从代码中移出:

    (defun write-lookup (binding-list pattern fact)
      (cond ((not binding-list)                          ; No bindings have been stored
             (cons (cons pattern fact) nil))             ; Return the binding list with a new one!
            (t                                           ; A list of bindings is being stored
             (cond ((equal (caar binding-list) pattern)  ; The current binding matches
                    (if (compare pattern fact)           ; Return the binding-list if value matches, nil else
                        binding-list
                      nil))   
                   ((cdr binding-list)                   ; Recursively search the rest list for the binding
                    (write-lookup (cdr binding-list) pattern fact))
                   (T                                    ; The list doesn't have the binding.
                    (cons (cons pattern fact)            ; Return the binding-list adding the pattern
                          binding-list)))))) 
    

    【讨论】:

    • 谢谢!丢失的 T 是罪魁祸首。
    • 嵌套的 COND 有什么作用吗?看起来将嵌套 COND 中的子句提升到主 COND 子句的级别会产生相同的结果。
    • @Vatine,这是一个很好的观察。我不想重写代码,但那是一回事。另外 (cons foo nil) = (list foo), ...
    【解决方案2】:

    您对 cond 的嵌套使用看起来很可疑。您可以使用 if 尝试以下形式:

    (defun write-lookup (binding-list pattern fact) ;未存储任何绑定 ;用新的绑定列表返回! (如果(不是绑定列表) (缺点(缺点模式事实)无) (条件 ;当前绑定匹配 (((等于(caar绑定列表)模式) ;如果值匹配,则返回绑定列表,否则返回 nil (如果(比较模式事实)绑定列表 nil)) ;递归搜索列表的其余部分以查找绑定 ((cdr binding-list) (write-lookup (cdr binding-list) 模式事实)) ;该列表没有绑定。 ;返回具有添加模式的绑定列表 (T (cons (cons pattern fact) binding-list)))))

    对于格式的细微变化,我们深表歉意; emacs 喜欢把 cmets 放在右边。

    【讨论】:

    • 我认为这个级别的 cmets 的约定是 ;;,Emacs 很乐意将它缩进到与您的代码相同的位置。
    猜你喜欢
    • 2021-04-27
    • 2011-06-05
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多