読者です 読者をやめる 読者になる 読者になる

きくらげ観察日記

好きなことを、適当に。

named let

Gauche

Gauche(に限らずほぼすべてのLISP)では、letは次のようなシンタックスシュガーとなっています。

(let ((hoge hoge-value)
      (fuga fuga-value))
  (some-function hoge fuga))

;; ↓展開後

((lambda (hoge fuga)
   (some-function hoge fuga))
   hoge-value fuga-value)

このlambda自体に名前を付けて、再帰的に呼び出せるようにしたものがnamed letです。

これが何の役に立つかというと、例えば末尾再帰的な関数を簡単に書くことができるようになります。


試しに、lengthを自前で実装してみましょう。
まずは通常の末尾再帰のバージョンから。

(define (my-length lis)
  (define (my-length-rec xs n)
    (if (null? xs)
        n
        (my-length-rec (cdr xs) (+ n 1))))
  (my-length-rec lis 0))

これをnamed letを使って書き直すと、次のようになります。

(define (my-length2 lis)
  (let loop ((xs lis)
             (n 0))
    (if (null? xs)
        n
        (loop (cdr xs) (+ n 1)))))