1
2

More than 3 years have passed since last update.

Schemeのnamed-letのサンプル

Last updated at Posted at 2020-07-16

Schemeのnamed-letの記述例.いつものようにGaucheで実行確認.

named-let.scm
gosh> (define (sum x y l) ; named-letを使用しない.
        (cond ((> x y) (reverse l))
              (else
                (sum (+ x 1) y (cons x l)))))
sum
gosh> (sum 3 11 '())
(3 4 5 6 7 8 9 10 11)
gosh> (define (sum x y l)
        (let loop ((x x) (l l)) ; named-letを使用する.
          (cond ((> x y) (reverse l))
                (else
                  (loop (+ x 1) (cons x l))))))
sum
gosh> (sum 3 11 '())
(3 4 5 6 7 8 9 10 11)
gosh> (define sum ; lambda式のdefine形式にする.
        (lambda (x y l)
          (let loop ((x x) (l l)) ; named-letを使用する.
            (cond ((> x y) (reverse l))
                  (else
                    (loop (+ x 1) (cons x l)))))))
sum
gosh> (sum 3 11 '())
(3 4 5 6 7 8 9 10 11)
gosh>

どれも同じ内容でどんどん長くなっているけど,本質は3番目かもしれないと思っていたり.つまり,無名関数であるlambda式で再帰関数が定義できるということで.たとえば,こんな記述が書けたり…してもあんまし意味ないか.むう.

※2020-08-02追記:いや,意味大いにあるか.map無名再帰関数を指定しているということではないか….

map-lambda.scm
gosh> (map (lambda (p)
            (let loop ((x (car p)) (y (cadr p)) (l '()))
              (cond ((> x y) (reverse l))
                    (else
                     (loop (+ x 1) y (cons x l))))))
           '((1 5) (4 9) (3 8)))
((1 2 3 4 5) (4 5 6 7 8 9) (3 4 5 6 7 8))
gosh>

※2020-08-17追記:named-letをletrecでマクロ定義してみた例.

gosh> (define-syntax nlet
        (syntax-rules ()
          ((_ fn ((n v) ...) body)
           (letrec ((fn (lambda (n ...) body))) (fn v ...)))))
#<undef>
gosh> (nlet loop ((n 40) (f1 0) (f2 1))
        (if (= n 0) f1 (loop (- n 1) f2 (+ f1 f2))))
102334155

参考文献

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2