我需要实现一个函数,该函数接受一个或多个表达式并按顺序执行这些表达式。
这是我到目前为止所拥有的:
(define (foo exp0 exp1 ) exp0 exp1)
我需要实现一个函数,该函数接受一个或多个表达式并按顺序执行这些表达式。
这是我到目前为止所拥有的:
(define (foo exp0 exp1 ) exp0 exp1)
假设您有以下表达式
(sequence form1 form2 form3)
并且您希望按顺序评估表单,然后您不能将它们传递给 Josuha 解释的函数。最简单的转换是将上述更改为
((lambda () form1 form2 form3))
因为 lambda 表达式中的表单是按顺序执行的,结果是最后一个表单的值。由于必须在源代码级别完成此转换,因此您必须使用宏,例如:
(define-syntax-rule (sequence form1 form2 ...)
((lambda () form1 form2 ...)))
这将转换一个表达式,例如
(sequence (display "a") (display "b") (display "c"))
进入
((lambda () (display "a") (display "b") (display "c")))
它将按顺序执行表格。
Scheme 没有指定任何特定的参数评估顺序。这意味着如果你有一个display-and-return
函数:
(define (display-and-return x)
(display x)
x)
然后你打电话给,例如,
(list (display-and-return 1) (display-and-return 2))
您一定会得到结果(1 2)
,但您可以看到display 产生的输出12
为或21
。但是,Scheme 确实指定函数的参数将在函数体被计算之前被计算。因此,您可以通过将两个表达式作为函数的参数来对它们进行排序:
((lambda (val1)
((lambda (val2)
(list val1 val2))
(display-and-return 2)))
(display-and-return 1))
一般来说,你可以使用这样的转换(seq exp1 exp2 ... expm expn)
变成
((lambda (val1)
((lambda (val2)
...
((lambda (valm)
expn) ; or ((lambda (valn) valn) expn)
expm) ... )
exp2))
exp1)
您可以使用define-syntax-rule
.
您需要接受“一个或多个表达式”然后评估它们并返回最后一个的东西。这可以定义为:
(define (sequence exp1 . exps)
(car (reverse (cons exp1 exps)))) ; (if (null? exps) exp1 ...)
然后,您可以将其调用为:
> (sequence (+ 1 2) (* 1 2) 17)
17
不需要使用定义语法的东西,因为标准函数应用程序将“按顺序执行这些表达式”
如果您需要保证从左到右的顺序,那么您需要:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
(begin exp expos ...))))
但如果你不能使用begin
,但可以使用lambda
,那么:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
((lambda () exp exps ...)))))