在Scheme返回值中有一个函数(或做其他事情)并调用自身

时间:2013-09-25 13:33:57

标签: scheme

我想在函数体中评估两个表达式。我该怎么做呢?

鉴于以下内容:

(define (f)
  ((+ 2 2) (+ 4 4)))

我希望两者都有2 + 2和4 + 4的评估(显然上面的方法不起作用)。

基本上,如果我理解正确,在我可以完成一件事情的地方,我想做两件事。例如,我不想只调用一个函数作为if表达式的结果,而是想调用两个函数。或者理想情况下返回一个值并让函数调用自己。

我不确定这是否有意义,但概念上有这样一种机制似乎是合理的。

3 个答案:

答案 0 :(得分:12)

过程的主体从上到下进行求值,无论开头有多少个表达式,只返回最后一个的值。例如,如果我们写这个:

(define (f)
  (+ 2 2)  ; evaluates to 4, but we don't do anything with it, so it's lost
  (+ 4 4)) ; evaluates to 8, this is the returned value

...当我们调用(f)时,返回的值为8,第一个表达式的值将丢失。也许你想说,你想要返回多个值?这可能取决于解释器,例如在Racket:

(define (f)
  (values (+ 2 2) (+ 4 4)))

(f)
=> 4
   8

现在(f)返回两个值,如果我们要使用它们,我们需要特殊的表单来“捕获”多个返回的值。在此示例中,我将使用let-values

(let-values (((x y) (f))) ; 4 is bound to x, 8 is bound to y
  (+ x y))
=> 12

关于使用if表达式的问题的另一种解释:如果需要在if内写入多个表达式,则必须将所有表达式打包在begin中1}}形式(顺便说一句:过程的主体隐含在begin内。)

再次,即使所有的表达式都按顺序执行,只返回最后一个的值作为结果 - 所以中间的所有表达式只应该为效果执行,不是为了价值。例如:

(if (= 1 1)    ; condition is true
    (begin     ; execute a sequence of expressions
      (+ 2 2)  ; evaluates to 4, but the value is lost
      (+ 4 4)) ; evaluates to 8, this is the returned value
    (begin
      (+ 1 1)
      (+ 3 3)))
=> 8

当然,在上面的示例中,使用cond更简单,它具有隐式begin。这相当于前面的代码段:

(cond
  ((= 1 1)   ; condition is true, implicit `begin`
   (+ 2 2)   ; evaluates to 4, but the value is lost
   (+ 4 4))  ; evaluates to 8, this is the returned value
  (else
   (+ 1 1)
   (+ 3 3)))
=> 8

答案 1 :(得分:1)

我不确定我明白你的意思,你只需要一个接一个地调用这些函数:

(define (f)
  (display "calling-function-1")
  (newline)
  (display "calling-function-2"))

输出:

Welcome to DrRacket, version 5.3.5 [3m].
Language: SICP (PLaneT 1.17); memory limit: 128 MB.
> (f)
calling-function-1
calling-function-2

如果你这样做,还有:

(define (f)
  (+ 2 2) (+ 4 4))

它仍然可以正常工作,只返回最后一个值:

Welcome to DrRacket, version 5.3.5 [3m].
Language: SICP (PLaneT 1.17); memory limit: 128 MB.
> (f)
8

答案 2 :(得分:1)

如果要在只允许一个表达式的地方评估一系列表达式(即if结果),则需要使用begin。对于define的正文而言,情况并非如此。