Macros 从sicp宏中的周围抽象捕获变量
我试图在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)
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
,它绑定在函数/macrocompose
中的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;应用于所有函数
不知道组合
宏中的环境。