我需要实现一个带有一个或多个表达式的函数,并按顺序执行这些表达式。
这是我到目前为止所做的:
(define (foo exp0 exp1 ) exp0 exp1)
答案 0 :(得分:1)
假设您有以下表达式
(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")))
将按顺序执行表单。
答案 1 :(得分:0)
Scheme不指定任何特定的参数评估顺序。这意味着如果您有display-and-return
函数:
(define (display-and-return x)
(display x)
x)
然后你打电话,例如,
(list (display-and-return 1) (display-and-return 2))
您可以保证获得结果(1 2)
,但您可以看到显示为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
定义这种转换。
答案 2 :(得分:-1)
你需要一些带有“一个或多个表达式”的东西,然后对它们进行评估并返回最后一个。这可以通过以下方式定义:
(define (sequence exp1 . exps)
(car (reverse (cons exp1 exps)))) ; (if (null? exps) exp1 ...)
然后您将其调用为:
> (sequence (+ 1 2) (* 1 2) 17)
17
不需要使用define-syntax stuff,因为标准函数应用程序将“按顺序执行那些表达式”
如果您需要从左到右保证订单,那么您需要:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
(begin exp expos ...))))
但如果您无法使用begin
,但可以使用lambda
,那么:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
((lambda () exp exps ...)))))