首页 > 解决方案 > 使用 cond 运算符的 Parens 'options'?

问题描述

我决定整理以下功能。这个想法是它使用cond但它也包含ifs,这使得认知处理变得困难。这是来自 ansi common lisp 一书的 bst 代码。

(defun percolate (bst)                      
  (cond ((null (node-l bst))                
         (if (null (node-r bst))
             nil
             (rperc bst)))
        ((null (node-r bst)) (lperc bst))
        (t (if (zerop (random 2))
               (lperc bst)
               (rperc bst)))))

我的想法是通过在 中添加更多案例来删除 ifs,cond然后用左边的原因很好地证明整个事情,右边的效果。这是我想出的:

(defun percolate (bst)                      ; [6,7,7a]
  (cond (((and (null (node-l bst)) (null (node-r bst)))  nil)
         ((null (node-l bst))                            (rperc bst))
         ((null (node-r bst))                            (lperc bst))
         (t                                              (if (zerop (random 2))
                                                             (lperc bst)
                                                             (rperc bst))))))

但是,这会产生错误

*** - SYSTEM::%EXPAND-FORM: (AND (NULL (NODE-L BST)) (NULL (NODE-R BST))) should be a
      lambda expression

我可以在堆栈溢出上找到有关此问题的其他帖子,例如此处,但我仍然不明白。cond 是否以某种方式偏离了正常的 lisp 语法?我想确定我所做的假设是错误的。

作为记录,下面的代码被解释器接受,但显然我们不想这样写。

(defun percolate (bst)                      ; [6,7,7a]
  (let ((both-null (and (null (node-l bst)) (null (node-r bst))))
        (l-null    (null (node-l bst)))
        (r-null    (null (node-r bst))))
  (cond ((both-null                                              nil)
         (l-null                                         (rperc bst))
         (r-null                                         (lperc bst))
         (t                                              (if (zerop (random 2))
                                                             (lperc bst)
                                                             (rperc bst)))))))

标签: common-lisp

解决方案


cond句法:

cond {clause}*

clause::= (test-form form*) 

例子

(cond (var)
      (var a b c)
      (var (f a) (f b) (f c))
      ((and var-a var-b) (f c) (f d))
      ((f a) b (f c) d)
      (t (f a) (f b) (f c)))

方法:

  • 零个或多个子句。
  • 每个子句都在一个列表中,以一个测试表格开头,然后是零个或多个表格

let句法:

let ({var | (var [init-form])}*)
  declaration*
  form*

方法:

  • 一个列表中的零个或多个可变子句
  • 每个变量子句要么是一个变量,要么是一个变量列表和可选的 init-form
  • 可变子句列表后跟可选的零个或多个声明,然后是零个或多个主体形式

例子:

(let ()
   )

(let (a)
  a)

(let (a
      (b t))
  (and a b))

(let ((a t)
      (b (not t)))
  (or a b))

推荐阅读