Scheme修行11章

11章を読んでいたのでメモと感想をまとめてみます。

メモ

  • Scheme手習いの続きなので11から始まる。
  • 究極のλを知っていますか?
  • two-in-a-row-b?は2つの引数が変わるのに、質問は1つの引数についてのみ
  • p10「一方の引数は他方の引数について関数に何かを伝えます」
    • このトリックは面白い
    • two-in-a-row-bのprecedingではlatの引数の前の要素を
    • sum-of-prefixes-bのsonssfはこれまでの全ての数の合計を
    • scramble-bのrev-preは自分より前の部分の逆を
  • 第11の戒律「ある関数が、その関数に対する他の引数がいかなるものか知る必要があるときは、付加的な引数を用いるべし。」
  • 出てきてる用語
    • parsleyはパセリ
    • sardinesはイワシ
    • sonssfは「sum of numbers seen so far.(それまで見てきた数の合計)」の略
    • scrambleのニュアンスがちょっと分からない
    • rev-preはreversed prefix
  • 前章で定義してあったone?やpickなどの手続きを使っているので、11.scmの先頭に定義した
    • atom?等、他の章でも使うものは共通のファイルに抜き出していこうと思う。
  • 「関数の手がかりは、いつだってその名前です。」
    • いい名前は理解を助けてくれますね。
  • 食事の回数、3回
    • p13 「覚えているならアイスクリームを食べましょう」
    • p15 「スナックを食べる前に」
    • p15 「お茶の時間です。」

感想

「はじめに」によると「食べ物がちょっとした気晴らしになってこの本を一度にたくさん読まないで済むことを願っている」らしい。
でも面白いから読み始めると1章、一気に読んでしまいますね。
読んでから少し時間が経ってしまったので理解しているか確かめるためにthree-in-a-row?を定義してみた。

(define three-in-a-row-b?
  (lambda (preceding1 preceding2 lat)
    (cond ((null? lat) #f)
          (else (or (and (eq? preceding1 preceding2)
                         (eq? preceding2 (car lat)))
                    (three-in-a-row-b? preceding2 (car lat) (cdr lat)))))))

(define three-in-a-row?
  (lambda (lat)
    (cond ((null? lat) #f)
          ((null? (cdr lat)) #f)
          (else (three-in-a-row-b? (car lat) (car (cdr lat)) (cdr (cdr lat)))))))

で、n-in-a-row?を定義したくなったので色々といじっていたらいつの間にかYコンビネータを書いたり

(define Y
  (lambda (f)
    ((lambda (x) (x x))
     (lambda (x) (f (lambda (y) ((x x) y)))))))

(define L
  (lambda (length)
    (lambda (l)
      (cond ((null? l) 0)
            (else (+ 1 (length (cdr l))))))))

(define T
  (lambda (take)
    (lambda (nl)
      (cond ((= 0 (car nl)) '())
            (else (cons (car (car (cdr nl)))
                        (take (cons (- (car nl) 1)
                                    (cons (cdr (car (cdr nl)))
                                          '())))))))))
(define length (Y L))
(define take (Y T))

(define n-in-a-row?
  (lambda (n)
    (Y (lambda (n-in-a-row?)
         (lambda (lat)
           (cond ((> n (length lat)) #f)
                 (else (or ((Y ((lambda (a)
                                  (lambda (every)
                                    (lambda (lat)
                                      (cond ((null? lat) #t)
                                            ((eq? a (car lat))
                                             (every (cdr lat)))
                                            (else #f)))))
                                (car lat)))
                            (take (cons n (cons lat '()))))
                           (n-in-a-row? (cdr lat))))))))))

それを無名にしてみたり

(define n-in-a-row?
  (lambda (n)
    ((lambda (f)
       ((lambda (x) (x x))
        (lambda (x) (f (lambda (y) ((x x) y))))))
     (lambda (n-in-a-row?)
       (lambda (lat)
         (cond ((> n (((lambda (f)
                         ((lambda (x) (x x))
                          (lambda (x) (f (lambda (y) ((x x) y))))))
                       (lambda (length)
                         (lambda (l)
                           (cond ((null? l) 0)
                                 (else (+ 1 (length (cdr l)))))))) lat)) #f)
               (else
                (or (((lambda (f)
                        ((lambda (x) (x x))
                         (lambda (x) (f (lambda (y) ((x x) y))))))
                      ((lambda (a)
                         (lambda (every)
                           (lambda (lat)
                             (cond ((null? lat) #t)
                                   ((eq? a (car lat)) (every (cdr lat)))
                                   (else #f)))))
                       (car lat)))
                     (((lambda (f)
                         ((lambda (x) (x x))
                          (lambda (x) (f (lambda (y) ((x x) y))))))
                       (lambda (take)
                         (lambda (nl)
                           (cond ((= 0 (car nl)) '())
                                 (else (cons (car (car (cdr nl)))
                                             (take (cons (- (car nl) 1)
                                                         (cons (cdr (car (cdr nl)))
                                                               '())))))))))
                      (cons n (cons lat '()))))
                    (n-in-a-row? (cdr lat))))))))))

なんかこの章の理解を確かめるというより究極のlambda復習してしまった orz