letrec

letrec は局所関数を定義する一般的な方法だそうだ。

 cf. 7. 繰り返し – もうひとつの Scheme 入門

let と違って定義内で自分の名前を参照できるので、再帰関数を定義することができる。
例を示そう。↓これは以前書いた take。define を使って局所関数 f を定義している。

(define take
  (lambda (n lis)
    (define f
      (lambda (m l1 l2)
        (if (= m 0)
            (reverse l2)
            (f (- m 1) (cdr l1) (cons (car l1) l2)))))
    (f n lis '())))

これを letrec を使って書き直すとこうなる。

(define take
  (lambda (n lis)
    (letrec ((f (lambda (m l1 l2)
                  (if (= m 0)
                      (reverse l2)
                      (f (- m 1) (cdr l1) (cons (car l1) l2))))))
      (f n lis '()))))

(print (take 2 '(1 2 3 4 5)))

3行目(から6行目)で局所関数に f という名前をつけている。そして6行目でその f を再帰的に呼び出している。
実行結果:

^o^ > gosh take-letrec.scm
(1 2)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください