むっつめ

Scheme のお勉強

Emacs Lispをいろいろさわっているので、
『プログラミング Gauche』を久しぶりに開いてみた。

Emacs Lisp は Common Lispの系統だから、Scheme系のGaucheとはいろいろ違いがある。
このGaucheの本を読んだの、もう2年ぐらい前になるやろなあ。いや、もうちょい前か。
またその頃、『Scheme手習い』という本も読んでたなあ。
『Land of Lisp』も読んでた。まあ、こっちは Common Lisp やけど。
全部、図書館で借りて読んでた。『プログラミング Gauche』は買ったけどね。
Lisp系言語は勉強し始めたばかりだったから、なかなか理解できなかった。car とか cdr とか cons とか、手続き型言語にはないものがいっぱいあった。今はもう慣れたけど。

さて、Lisp言語は関数型言語ということで、再帰処理を簡潔に記述できるという特徴がある。
で、この本には、再帰処理を使った練習問題がある。

練習問題

(p56より引用)

さて、そろそろ再帰的な考え方に慣れてきましたか? 次の練習もやってみてください。
・リストの長さを計算する length を直接(foldを使わずに)定義してみる
・リストの中から、条件を満たす要素だけを抜き出したリストを返す filter を定義してみる


解答(ひとつめ)

;;; -*- cofing: utf-8 -*-
;;; get-length.scm
;;; p56
;;; リストの長さを計算する length を fold を使わずに定義する
(use srfi-1)

(define (length lis)
  (define (inner-length lis n)
    (if (null? lis)
        n
        (inner-length (cdr lis) (+ n 1))))
  (inner-length lis 0))

length手続きの中に、内部手続きinner-length を入れてみた。

こういうの、『Scheme手習い』の中に、腐るほど練習問題あったように思う。

解答(ふたつめ)

;;; -*- cofing: utf-8 -*-
;;; filter.scm
;;; p56
;;; リストの中から、条件を満たした要素だけを抜き出したリストを作成する
(use srfi-1)

(define (filter term lis)
  (define (filter-in lis l)
    (cond ((null? lis) l)
          ((term (car lis))
           (filter-in (cdr lis)(cons (car lis) l)))
          (else (filter-in (cdr lis) l))))
  (filter-in lis '()))

ここのとこ、思い出すのに少し時間がかかった。

cond式の中で、条件が満たしたときは、この式

 (filter-in (cdr lis) (cons (car lis) l))


条件を満たさなかったときは、この式

 (filter-in (cdr lis) l)

ここがおもしろいところやな。

Scheme系Lispやってたら、Gaucheでなにかアプリケーションを作りたくなってきた。
なにか考えてみようかなあ。

参考文献

『プログラミング Gauche』Kahuaプロジェクト・著 川合史朗・監修 オライリー・ジャパン 2008年3月13日 初版第1刷

『Scheme手習い』 Daniel P.Friedman・Matthias Felleissen・共著 元吉文男・横山晶一・翻訳 オーム社 2010年10月22日

『Land of Lisp』M.D.ConradBarski・Conrad Barski・著 川合史朗・翻訳 オライリージャパン 2013年2月23日