1. ホーム
  2. scheme

[解決済み] ラケットビギナーズフォーム

2022-02-08 13:19:17

質問

(define mystery2 
  (lambda (L)
    (if (null? L)
        L
        (begin
          (displayln L)
          (append (mystery2 (cdr L))
                  (list (car L)))))))

で実行しています。 (mystery2 '((1 2) (3 4) 5 6))

ここで、"begin"関数が何をするものなのかがよくわかりません。

また、"displayln L" と書くと、以下のようにしか表示されません。 ((1 2) (3 4) 5 6)) . 再帰なので、減少する値をプリントしてはいけないのでしょうか?

なぜここで "begin" が使われ、displayln がそのように動作するのか、理解するのを助けてください。

コード自体に問題はありません。

どのように解決するのですか?

その begin フォームが使用されます。 if は、各ブランチに1つの式しか入れられません。

より直感的な例としては、デバッグが挙げられるでしょう。難しいコードを書いているときに、どのブランチが実行されるかを確認したいとします。

元のコード

(if (true? some-value)
    (dostuff)
    (dostuff2))

しかし、どちらのブランチが実行されたか分からないので、どちらかのブランチが実行されるたびにメッセージを表示させたいと思うかもしれません。しかし Scheme は各ブランチにひとつの式しか置くことができないので、ただ置くだけではダメなのです。ひとつの式にまとめなければなりません。 begin .

(if (true? some-value)
    (begin
      (display "some-value was true")
      (dostuff))
    (begin 
      (display "some-value was false")
      (dostuff2)))

Beginは任意の数の式を受け取り、それぞれを実行しますが、ボディにある最後の式の結果のみを返します。