首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数实现与宏实现的区别

函数实现与宏实现的区别
EN

Stack Overflow用户
提问于 2016-11-02 05:35:55
回答 2查看 89关注 0票数 0

“什么时候”的这些实现之间到底有什么不同?

代码语言:javascript
复制
(define-syntax when
  (syntax-rules ()
    ((_ pred b1 ...)
     (if pred (begin b1 ...)))))

代码语言:javascript
复制
(define (my-when pred b1 ...)
  (if pred (begin b1 ...)))

例如,在这个For循环宏中使用‘my- this’时:

代码语言:javascript
复制
(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)) ;中止!:超过最大递归深度

我不认为“什么时候”可以作为一个函数来实现,但我不知道为什么.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-02 12:51:35

方案具有严格的语义。

这意味着函数的所有参数在应用于函数之前都要进行计算。

宏接受源代码并生成源代码--它们不计算任何参数。

(或者,我想是这样的,但它们的参数是语法-语言元素-而不是您通常认为的值,例如数字或字符串。宏编程就是元编程.重要的是要知道你在哪一层编程。)

在您的示例中,这意味着当my-when是一个函数时,必须对(loop (+ i 1))进行计算,然后才能将my-when应用于它。

这将导致无限递归。

当它是宏时,首先将my-when表单替换为等效的if-form

代码语言:javascript
复制
 (if (< i to)
     (begin
         b1 ...
         (loop (+ i 1))))

然后对整个过程进行评估,这意味着(loop (+ i 1))只在条件为真时才得到评估。

票数 0
EN

Stack Overflow用户

发布于 2016-11-02 12:49:13

如果像以前一样将when作为一个过程来实现,那么所有的参数都会被计算出来。在您的for实现中,评估将按如下方式处理:

  1. 评估(< i to)
  2. b1 ...的扩展效果评价
  3. 评估(loop (+ i 1)) <-这里进入无限循环!
  4. 评估my-when

项目1-3可以是反向的,也可以是未定义的顺序,这取决于您的实现,但重点是nr。4.如果将my-when实现为宏,则该宏是第一个要评估的宏。

如果您真的需要用一个过程来实现,那么您需要使用某种延迟技巧,比如thunk。例如:

代码语言:javascript
复制
(define (my-when pred body) (if (pred) (body)))
(my-when (lambda () (< i 10)) (lambda () (display i) (loop (+ i 1))))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40373120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档