1

関数本体で2つの式を評価したいと思います。どうすればいいですか?

以下を考えると:

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

2+2 と 4 + 4 の両方を評価したいと思います (明らかに、上記は機能しません)。

基本的には、正しく理解すれば、1つのことができる場所で、2つのことをやりたいと思っています。たとえば、if 式の結果として 1 つの関数だけを呼び出す代わりに、2 つの関数を呼び出したいとします。または理想的には、値を返し、関数自体を呼び出します。

これが理にかなっているのかどうかはわかりませんが、概念的にはそのようなメカニズムを持つことはもっともらしいようです.

4

3 に答える 3

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)戻り値 isを呼び出すと8、最初の式の値が失われます。おそらく、複数の値を返したいということでしょうか? これは、インタープリターによっては可能です。たとえば、Racket では次のようになります。

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

(f)
=> 4
   8

2 つの(f)値を返すようになりました。それらを使用する場合は、返された複数の値を「キャプチャ」するための特別なフォームが必要です。この例では、次を使用します。let-values

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

式の使用に関する質問の別の解釈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

もちろん、上記の例で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
于 2013-09-25T13:57:23.417 に答える
1

単一の式のみが許可されている場所 (つまりif結果) で一連の式を評価したい場合は、 を使用する必要がありますbegin。これは、 の本体には当てはまりませんdefine

于 2013-09-25T14:02:28.400 に答える
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
于 2013-09-25T13:48:18.007 に答える