2

我需要实现一个函数,该函数接受一个或多个表达式并按顺序执行这些表达式。

这是我到目前为止所拥有的:

(define (foo exp0 exp1 ) exp0 exp1)
4

3 回答 3

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")))

它将按顺序执行表格。

于 2013-10-09T19:04:49.697 回答
0

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.

于 2013-10-09T18:36:34.447 回答
-1

您需要接受“一个或多个表达式”然后评估它们并返回最后一个的东西。这可以定义为:

(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 ...)))))
于 2013-10-09T23:03:07.660 回答