Mic*_*ael 6 scheme eval guile quote
这似乎是一个简单的问题; 也许它很简单,很难找到能找到答案的搜索.在Scheme(特别是Guile实现,如果这有任何区别)我如何评估已被引用的内容?
这就是我想要做的.
我基本上需要确保我定义的函数以特定顺序计算其参数,因为在评估其他参数期间,评估一个参数所引起的副作用是依赖的.但是,Scheme表示可以按任何顺序计算参数,因此我想通过引用参数手动强制它,然后按所需的顺序手动评估它们.
似乎"eval" 应该做我想要的,但它有两个问题:
我尝试过其他技巧,比如建立一个lambda:
(list 'lambda '() '(car (b c)))
Run Code Online (Sandbox Code Playgroud)
但似乎必须对此进行评估以生成程序.我也尝试过:
(list lambda '() '(car (b c)))
Run Code Online (Sandbox Code Playgroud)
但这会返回一个"原始内置宏",它也不起作用.
编辑:看起来宏将用于控制评估顺序:(defmacro test1(ab)`(begin,b,a))
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) ....)
Run Code Online (Sandbox Code Playgroud)
或者defmacro,如果必须,请使用.
如果您需要评估列表结构(带有代表Scheme程序文本的带引号符号的嵌套列表),那么您应该使用eval. 方案要求传递一个环境作为第二个参数,即使它是当前环境:
(eval '(+ x y) (interaction-environment))
Run Code Online (Sandbox Code Playgroud)
begin如果您只需要按特定顺序进行计算,则可以通过使用、let或仅使用函数体来强制执行副作用的计算顺序。他们定义了一系列评估:
(let ((x 42))
; eval with effects #1
(display x)
; eval with effects #2
(display (+ x 1)))
Run Code Online (Sandbox Code Playgroud)
编辑:如果您需要一个参数化的代码块,您可以在其中传递未求值的表达式,然后强制按某种特定顺序求值,那么您可以使用以下技术之一:
一个宏(正如您已经提到的,只是为了完整性):
> (defmacro test1 (a b) `(begin ,b ,a))
> (test1 (display 2) (display 3)
32
Run Code Online (Sandbox Code Playgroud)延迟计算(Scheme 用于延迟计算的特殊语法):
> (define (test1 a b) (begin (force b) (force a)))
> (test1 (delay (display 2)) (delay (display 3)))
32
Run Code Online (Sandbox Code Playgroud)常规 lambda 抽象和应用
> (define (test1 a b) (begin (b) (a)))
> (test1 (lambda () (display 2)) (lambda () (display 3)))
32
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |