lisp - 如何定义惰性 AND

标签 lisp common-lisp lazy-evaluation

我定义了以下宏:

(defmacro ~lazy (expression)
  `(lambda ()
     ,@expression))

(defgeneric force~ (value)
  (:method (value)
    value)
  (:method ((value function))
    (funcall value)))

(defmacro ~~ (expression)
  `(~lazy (force~ ,expression)))

[...] 以下宏定义了一个名为“NAME”的通用函数,其中定义了一些标准方法。这应该像“REDUCE”一样工作,并在途中强制所有惰性值,同时在它甚至曾经遇到一个惰性值时返回一个惰性值,否则返回一个非惰性值(由以“~”开头和结尾的宏表示)。

(defmacro ~lazy-reduce~ (name reduce-fun (arg-var args-var)
                         &body methods)
  (let ((first (gensym "first")))
    `(defgeneric ,name (,arg-var ,args-var)
       ,@(append
          (if (not (member `(,arg-var (,args-var cons))
                           methods
                           :key #'car
                           :test #'equal))
              `((:method (,arg-var (,args-var cons))
                  (let ((,first (first ,args-var)))
                    (if (functionp ,first)
                        (~~ (,reduce-fun (force~ ,first)
                                         (force~
                                          (,name ,arg-var
                                                 (rest ,args-var)))))
                        (,name (,reduce-fun ,arg-var ,first)
                               (rest ,args-var)))))))
          (if (not (member `((,arg-var function)
                             ,args-var)
                           methods
                           :key #'car
                           :test #'equal))
              `((:method ((,arg-var function)
                          ,args-var)
                  (~~ (,name (force~ ,arg-var)
                             ,args-var))))))
       ,@(mapcar (lambda (method)
                   (cons :method method))
                 methods))))

现在我这样定义 ~_AND~ :

(~lazy-reduce~ ~_and~ and (val vals)
   (((val null)
     vals)
    nil)
   ((val (vals null))
    val))

打电话

(~_and~ t (list 2))

工作正常并按预期返回“2”

(force~ ~_and~ t (list (~ 2)))

仅返回“T”。

我不知道为什么会这样,这让我无法简洁地定义“~FIND-IF”。

最佳答案

我发现了我的错误:~_AND~ 的第一种方法如下所示:

(:method (val (vals cons))
 (let ((first (first vals)))
   (if (functionp first)
       (~~ (and (force~ first)
                (force~ (~_and~ val (rest vals)))))
       (~_and~ (and val first)
               (rest vals)))))

(这可以通过 MACROEXPAND-1 在给定的 ~_AND~ 定义上看出)

这意味着显示的调用被(粗略地)评估为

(and (force~ (~ 2))
     T)

如所见,这将返回“T”。

关于lisp - 如何定义惰性 AND,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15812679/

相关文章:

dictionary - 我的程序的map/zipmap部分会消耗太多内存吗?

kotlin - “lazy”在Kotlin中的这段代码是什么意思?

oop - 当第一个参数为 nil 时无法调用方法?

clojure:没有cons细胞

function - Common Lisp中#'callee and '被调用者之间的区别

recursion - 查找由列表组成的方阵的对角线

debugging - "is not of type LIST"错误

java - 如何获取每个无序元素对,而不懒惰地从两个列表中重复?

deployment - 需要反馈 : non-disruptive deployment strategies for production Lisp webapps

lisp - 1-和1+的历史