“什么时候”的这些实现之间到底有什么不同?
(define-syntax when
(syntax-rules ()
((_ pred b1 ...)
(if pred (begin b1 ...)))))与
(define (my-when pred b1 ...)
(if pred (begin b1 ...)))例如,在这个For循环宏中使用‘my- this’时:
(define-syntax for
(syntax-rules ()
((_ (i from to) b1 ...)
(let loop((i from))
(my-when (< i to)
b1 ...
(loop (+ i 1)))))))发生错误:
(用于(i 0 10) (显示i)) ;中止!:超过最大递归深度
我不认为“什么时候”可以作为一个函数来实现,但我不知道为什么.
发布于 2016-11-02 12:51:35
方案具有严格的语义。
这意味着函数的所有参数在应用于函数之前都要进行计算。
宏接受源代码并生成源代码--它们不计算任何参数。
(或者,我想是这样的,但它们的参数是语法-语言元素-而不是您通常认为的值,例如数字或字符串。宏编程就是元编程.重要的是要知道你在哪一层编程。)
在您的示例中,这意味着当my-when是一个函数时,必须对(loop (+ i 1))进行计算,然后才能将my-when应用于它。
这将导致无限递归。
当它是宏时,首先将my-when表单替换为等效的if-form
(if (< i to)
(begin
b1 ...
(loop (+ i 1))))然后对整个过程进行评估,这意味着(loop (+ i 1))只在条件为真时才得到评估。
发布于 2016-11-02 12:49:13
如果像以前一样将when作为一个过程来实现,那么所有的参数都会被计算出来。在您的for实现中,评估将按如下方式处理:
(< i to)b1 ...的扩展效果评价(loop (+ i 1)) <-这里进入无限循环!my-when项目1-3可以是反向的,也可以是未定义的顺序,这取决于您的实现,但重点是nr。4.如果将my-when实现为宏,则该宏是第一个要评估的宏。
如果您真的需要用一个过程来实现,那么您需要使用某种延迟技巧,比如thunk。例如:
(define (my-when pred body) (if (pred) (body)))
(my-when (lambda () (< i 10)) (lambda () (display i) (loop (+ i 1))))https://stackoverflow.com/questions/40373120
复制相似问题