我想在函数体中评估两个表达式。我该怎么做呢?
鉴于以下内容:
(define (f)
((+ 2 2) (+ 4 4)))
我希望两者都有2 + 2和4 + 4的评估(显然上面的方法不起作用)。
基本上,如果我理解正确,在我可以完成一件事情的地方,我想做两件事。例如,我不想只调用一个函数作为if表达式的结果,而是想调用两个函数。或者理想情况下返回一个值并让函数调用自己。
我不确定这是否有意义,但概念上有这样一种机制似乎是合理的。
答案 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
的正文而言,情况并非如此。