Scheme 方案中的控制性评价(guile)
这似乎是一个简单的问题;也许这是如此简单,很难找到一个搜索,将找到答案。在Scheme(特别是Guile实现,如果这有什么不同的话)中,我如何评估引用的内容 这就是我要做的 我基本上需要确保我定义的函数以特定的顺序计算其参数,因为计算一个参数所引起的副作用在计算其他参数时是依赖的。然而,Scheme说参数可以按任何顺序求值,所以我想通过引用参数,然后按需要的顺序手动求值来手动强制求值 “eval”似乎应该做我想做的事情,但它有两个问题:Scheme 方案中的控制性评价(guile),scheme,eval,quote,guile,Scheme,Eval,Quote,Guile,这似乎是一个简单的问题;也许这是如此简单,很难找到一个搜索,将找到答案。在Scheme(特别是Guile实现,如果这有什么不同的话)中,我如何评估引用的内容 这就是我要做的 我基本上需要确保我定义的函数以特定的顺序计算其参数,因为计算一个参数所引起的副作用在计算其他参数时是依赖的。然而,Scheme说参数可以按任何顺序求值,所以我想通过引用参数,然后按需要的顺序手动求值来手动强制求值 “eval”似乎应该做我想做的事情,但它有两个问题: 不鼓励使用它,所以我觉得应该有更好的方法来完成我想在这里做
(list 'lambda '() '(car (b c)))
但似乎必须对其进行评估才能生成一个过程。
我还尝试:
(list lambda '() '(car (b c)))
但这将返回一个“基本内置宏”,它也不起作用
编辑:
看起来宏将用于控制计算顺序:
(defmacro test1(a b)`(begin,b,a))如果需要评估列表结构(带有引号的嵌套列表,表示方案程序文本),则应使用
eval
。Scheme要求将环境作为第二个参数传递,即使它是当前环境:
(eval '(+ x y) (interaction-environment))
如果您只需要按特定顺序进行计算,则可以通过使用begin
、let
,或仅使用函数体来强制执行副作用的计算顺序。它们定义了一系列评估:
(let ((x 42))
; eval with effects #1
(display x)
; eval with effects #2
(display (+ x 1)))
编辑:如果您需要一个参数化的代码块,可以在其中传递未计算的表达式,然后按特定顺序强制计算,则可以使用以下技术之一:
- 宏(正如您已经提到的,只是为了完整性):
- 延迟计算(Scheme用于延迟计算的特殊语法):
- 正则lambda抽象及其应用
> (define (test1 a b) (begin (b) (a))) > (test1 (lambda () (display 2)) (lambda () (display 3))) 32
eval
对于改变参数的求值顺序来说是完全错误的工具。改为创建宏:
;; (my-fun e1 e2)
;; Just calls my-real-fun, but evaluates e2 before e1
(define-syntax my-fun
(syntax-rules ()
[(my-fun e1 e2)
;; let* has guaranteed order of evaluation
(let* ([y e2]
[x e1])
(my-real-fun x y))]))
(define (my-real-fun x y) ....)
如果必须的话,也可以使用
defmacro
。你通过lambdas的路线是正确的。如果你有
(define (f x y z) ...)
。。。那么你可以这样称呼它:
(f
(lambda () a)
(lambda () b)
(lambda () c))
这将以未计算的形式使用所有参数(a
,b
,c
)调用f
。在f
中,您完全有权选择评估顺序。唯一的区别是,您必须显式调用(x)
、(y)
和(z)
,并在定义或类语句中捕获它们的值。这样可以确保副作用只发生一次
这里根本不需要宏。顺便说一句,不要担心在任何地方都使用大量lambda,它们非常便宜。如果需要可变数量的参数,宏如何工作<代码>(defmacro test1(a.b)`(begin,b,a))
不起作用,因为b现在是一个列表。我需要以某种方式将它拼接到开头,但是各种尝试,例如`(begin(if(pair?,b)(test1,b)),a))
都不起作用。此外,我不能使用(defmacro test1(a.b)`(begin(apply begin,b),a))
,因为我不能应用宏。您错过的是(defmacro test1(a.b)`(begin,(cons'begin b),a))
(define (f x y z) ...)
(f
(lambda () a)
(lambda () b)
(lambda () c))