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

dre*_*ker 1 scheme

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

鉴于以下内容:

(define (f)
  ((+ 2 2) (+ 4 4)))
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ósc*_*pez 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
Run Code Online (Sandbox Code Playgroud)

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

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

(f)
=> 4
   8
Run Code Online (Sandbox Code Playgroud)

现在(f)返回两个值,如果我们要使用它们,我们需要特殊的表单来"捕获"多个返回的值.在这个例子中,我将使用let-values:

(let-values (((x y) (f))) ; 4 is bound to x, 8 is bound to y
  (+ x y))
=> 12
Run Code Online (Sandbox Code Playgroud)

对你的问题的另一种解释,关于if表达式的使用:如果你需要在一个表达式中写入多个表达式if,那么你必须将所有表达式打包在一个begin表单中(顺便说一下:一个过程的主体隐含在一个表达式中)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
Run Code Online (Sandbox Code Playgroud)

当然,在上面的例子中,只使用一个cond含有隐含的a更简单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
Run Code Online (Sandbox Code Playgroud)