末尾再帰の練習

まずはフツウの再帰で書いたもの。

(define myfilter
  (lambda (proc lis)
    (cond
      ((null? lis) '())
      ((proc (car lis)) (cons (car lis) (myfilter proc (cdr lis))))
      (else (myfilter proc (cdr lis))))))

(print (myfilter odd? '(1 2 3 4 5)))
takatoh@nightschool $ gosh myfilter.scm
(1 3 5)

で、こっちが末尾再帰で書いたもの。

(define myfilter-tail
  (lambda (proc lis)
    (letrec ((iter (lambda (l1 l2)
      (cond
        ((null? l1) (reverse l2))
        ((proc (car l1)) (iter (cdr l1) (cons (car l1) l2)))
        (else (iter (cdr l1) l2))))))
          (iter lis '()))))

(print (myfilter-tail odd? '(1 2 3 4 5)))

内部で iter という局所関数を定義して、それを呼び出している。

takatoh@nightschool $ gosh myfilter-tail.scm
(1 3 5)