Macros 在宏观定义中困惑
我想在SICP第3.5.1节中实现惰性流 首先,我定义了这两个函数Macros 在宏观定义中困惑,macros,common-lisp,sicp,lazy-sequences,Macros,Common Lisp,Sicp,Lazy Sequences,我想在SICP第3.5.1节中实现惰性流 首先,我定义了这两个函数 (defmacro delay (form) `(lambda () ,form)) (defun force (form) (when form (funcall form))) 当我们打电话时: (force (delay '(+ 1 2))) ;;=> (+ 1 2) (force (delay (+ 1 2))) ;;=> 3 那就行了。然后我继续定义“流氓”,但这次有了 似乎有两种方
(defmacro delay (form)
`(lambda () ,form))
(defun force (form)
(when form
(funcall form)))
当我们打电话时:
(force (delay '(+ 1 2)))
;;=> (+ 1 2)
(force (delay (+ 1 2)))
;;=> 3
那就行了。然后我继续定义“流氓”,但这次有了
似乎有两种方式:
(defmacro stream-cons (a b)
`(cons ,a ,(delay b)))
(defmacro stream-cons (a b)
`(cons ,a (delay ,b)))
我不认为他们有什么不同,但我错了!第一版
是错误的版本,调用时:
(force (cdr (stream-cons 'a (progn (print "hello") 2))))
;;=> (PROGN (PRINT "hello") 2)
(macroexpand '(stream-cons 'a (progn (print "hello") 2)))
;;=> (CONS 'A #<CLOSURE (LAMBDA # :IN STREAM-CONS) {25ABB3A5}>)
(force (cdr (stream-cons 'a (progn (print "hello") 2))))
;;
;; "hello"
;; => 2
(macroexpand '(stream-cons 'a (progn (print "hello") 2)))
;;=> (CONS 'A (DELAY (PROGN (PRINT "hello") 2)))
现在,我很困惑。谁能帮我弄清楚不同的地方
那两个呢?非常感谢
我的环境:Windows 32位,SBCL 1.1.4这是理解宏的一个重要概念 问题是,
,(延迟b)
在宏扩展时进行评估,即lambda
在适当的位置创建,并包裹在传递给它的文本值(即符号列表)上。所以你得到了一个常量函数,它总是返回相同的值——一个恰好是你的代码的列表
你可以这样想象:
,(delay '(progn (print "hello") 2)) => (lambda () '(progn (print "hello") 2))
在第二种变体(延迟,b)
:
这里需要注意的是,宏调用的参数是逐字传递的,没有计算。因此,delay
有效地接收一个被引用的列表(”(progn(打印“hello”)2)
)。逗号的作用是在它们满足时取消引用
(delay ,'(progn (print "hello") 2)) => (delay (progn (print "hello") 2))