Macros 从sicp宏中的周围抽象捕获变量

Macros 从sicp宏中的周围抽象捕获变量,macros,scheme,sicp,Macros,Scheme,Sicp,我试图在sicp中编写一个更高级别的函数,它接受可变数量的单参数函数,并返回另一个由所有传递函数组成的函数。假设更高级别的函数名为compose,那么执行(compose f g)应该返回函数fog或f(g(x)),其中f和g是一些单参数函数。 我正在使用sicp的define syntax构造来实现这一点,到目前为止,我有以下代码: (定义适用于所有函数的语法 (语法规则() ((适用于所有函数f)(f x)) ((适用于所有函数f g)(f(适用于所有函数g))) ((适用于所有函数f.g)

我试图在sicp中编写一个更高级别的函数,它接受可变数量的单参数函数,并返回另一个由所有传递函数组成的函数。假设更高级别的函数名为
compose
,那么执行
(compose f g)
应该返回函数
fog
f(g(x))
,其中f和g是一些单参数函数。 我正在使用sicp的define syntax构造来实现这一点,到目前为止,我有以下代码:

(定义适用于所有函数的语法
(语法规则()
((适用于所有函数f)(f x))
((适用于所有函数f g)(f(适用于所有函数g)))
((适用于所有函数f.g)(f(适用于所有函数f.g)))
))
(定义语法)
(语法规则(x)
((组成)(lambda(x)x))
((组成g)(lambda(x)(适用于所有函数g)))
((compose.g)(lambda(x)(适用于所有函数.g)))
))
在这段代码中,我试图捕获
x
,它绑定在函数/macro
compose
中的
lambda
中,但是当我创建一个复合函数并调用它的某个值时,我得到一个错误,即标识符
x
未绑定。 有人能解释一下我如何在上述设置中捕获变量,或者用其他方法来解决这个问题吗

谢谢!:)

... 或者用其他方法来解决这个问题。 我不明白为什么OP代码试图在这里使用宏来创建高阶过程。采用一个或多个过程参数的
compose
过程可以使用过程定义的点语法轻松编写

(define (compose f . fs)
  (if (null? fs)
      (lambda (x) (f x))
      (let ((g (apply compose fs)))
        (lambda (x) (f (g x))))))
这里,当只提供一个参数时,将返回一个将
f
应用于单个参数
x
的过程。否则,将返回将
f
应用于其余过程参数组合的过程,并将最终过程参数应用于单个参数
x

以下是REPL演示:

>(定义(双x)(*2x))
>(定义(倒数x)(/1 x))
>(定义(正方形x)(*x))
>(定义(添加1 x)(+x 1))
>(定义doros(组成双倒数平方)
>(定义rodos(组成倒数双正方形))
>(多罗斯4)
1/8
>(罗多斯4)
1/32
>(定义dosoaor(组成双平方加法1倒数))
>(定义soroaod(组成平方倒数加1双))
>(=(或4)
(双(平方)(加1(倒数4(()())))
#t
>(第4章)
25/8
>(=(索罗德4)
(平方(倒数)(加1(双4‘‘‘‘)’)
#t
>(索罗德4)
1/81
组合过程
doros
应首先将其参数平方,然后取结果的倒数,最后返回两次该结果。因此,
(doros 4)
应计算为
(*2(/1(*4))
==>
1/8
,如上面的REPL演示所示

类似地,
rodos
应该首先将其参数平方,然后将结果加倍,最后取该结果的倒数。因此
(rodos4)
应计算为
(/1(*2(*4))
==>
1/32
,与REPL结果相匹配


组成四个过程的测试也很成功。

是否有一些原因导致您没有将
compose
作为一个函数来编写,通常情况下会是这样的?我希望
compose
按照问题中的说明获取可变数量的参数,例如,如果我愿意,我还应该能够创建一些函数
f(g(h(x))
(任何
n
个函数的组合)。尽管我很好奇,为什么scheme在我的示例中不从它的封闭环境中捕获绑定?如果我们用命令式语言(如C)做同样的事情,那里的宏将从封闭过程中捕获绑定(在那里发生文本替换).@ArpitBhadauria--
语法规则
形式中的自由变量指的是定义宏的环境中的绑定,而不是使用宏的环境。对于顶层的宏,这意味着
定义中的自由
x
适用于所有函数
指的是to上不存在的绑定p level;
应用于所有函数
不知道
组合
宏中的环境。