トップ «前の日記(2010-05-23) 最新 次の日記(2010-06-02)» 編集

Route 477



2010-05-24

[lisp][scheme] 社内勉強会でLisp概論的な話をした

(以下、わりと適当な資料)

Lispといえば?

  • 最初の動的言語
  • 最初のGC付き処理系
  • 人工知能研究の言語として活躍
  • 括弧
  • マクロ

  • 1957年 FORTRAN
  • 1958年 ALGOL58, LISP
  • 1960年 COBOL
  • 1964年 BASIC

LISP戦国時代

  • 方言の乱立

LISP二大政党時代

Common Lisp (1984-)

Scheme (1975-)

  • ミニマリズム
  • 処理系間の独自拡張が多い
  • http://www.r6rs.org/
  • LISP-1
  • #tと#f ('()は真)
  • PLT Scheme, MIT Scheme, Guile, Chez Scheme(商用), ...
    • Gauche, SigScheme, Mosh, Ypsillon, BiwaScheme
  • 関数型、一級継続、末尾最適化の保証(←再帰)

もともとの開発の動機は、継続や末尾再帰といったプログラミングのコンセプトを使って、彼らが研究していた平行プログラミングにおける制御構造の理論を検証するためだったという。

[Scheme - Wikipediaより引用]

新党

4274067890

  • Clojure
    • JVM上で動作、並列
  • Nu
    • Objective-Cとの親和性
  • Cyan
    • Ruby/Python風の構文+Lispマクロ

速習Scheme (1) 評価方法

http://www.biwascheme.org/ でREPLを開いてください

基本形:

 (func a b c)

 (+ 1 2 3)
 (string-append "Hello, " "world!")

特殊フォーム:

 (if (= 1 1) (print 1) (print 2))
 (and 1 2)

(2) クオート

特殊フォーム「quote」

 (print (quote (+ 1 2 3)))  ; 評価されない
 (print '(+ 1 2 3))         ; 上の省略形

プログラムを、とても簡単にデータと同様に扱える

 (eval '(+ 1 2 3))

*1

シンボル

 (print a)  ;=> エラー
 (print 'a) ;=> シンボル「a」が表示される

Schemeのシンボルは、Rubyのシンボルと同じようなもの*2

(3) リスト

配列ではなく、連結リスト

 '(a b c)
 +---+---+   +---+---+   +---+----+
 |'a |  ---->|'b |  ---->|'c | () |
 +---+---+   +---+---+   +---+----+
 (car '(a b c))
 (cdr '(a b c))

4757727151 S式 = ツリー構造を書き下すための記法

 '((1 2) (3))
 +---+---+                   +---+---+
 |   |  -------------------->|   | ()|
 +-|-+---+                   +-|-+---+
   |  +---+---+   +---+---+    |  +---+----+
   +->| 1 | ----->| 2 | ()|    +->| 3 | () |
      +---+---+   +---+---+       +---+----+

最後のcdrに物を入れることもできる(「.」を使って表記する)

 '((1 . 2) (3 . 4))
 +---+---+    +---+---+    +---+---+
 |   |  ----->|   |  ----->|   | ()|
 +-|-+---+    +-|-+---+    +-|-+---+
   |  +---+---+ |  +---+---+
   +->| 1 | 2 | +->| 3 | 4 |
      +---+---+    +---+---+

(3) マクロ

  • 特殊フォームを自分で定義できる
  • defmacro(CL)/define-macro, syntax-rules(R5RS), syntax-case(R6RS)

例:

 (assert-equal (+ 1 2) 3)
 -> (if (equal? (+ 1 2) 3) #t (print "error in " "(+ 1 2 3)"))
 (assert-equal <code> <value>)
 -> (if (equal? <code> <value>) #t (print "error in " <code>))
 (define-macro (assert-equal code value)
   `(if (equal? ,code ,value) #t (print "error in " ',code)))
 (assert-equal (+ 1 2) 3)

 (assert-equal (+ 1 2) 4)
  • マクロは「コードを受け取ってコードを返す手続き」
    • プログラムをプログラミングする=メタプログラミング

参考文献

Common Lisp

  • 網羅的な4894714337
  • 作りながら学ぶ4274067211
  • 堅苦しくない4798119415
  • 関数型への入門4839920818

Scheme

  • 概要から応用まで4873113482
  • 対話で学ぶ0262560992 (※洋書。和訳は絶版)
  • 網羅的な4894712261
  • 名著にして積ん読489471163X

その他

  • Effective Macros4274066371
  • More Effective Macros4434133632
  • 新党4274067890
  • 名著*3にして鈍器4798118907

無料で読める原書リンク

*1 BiwaSchemeのevalは手抜き仕様なのでこれが通るが、本当は第二引数が必要

*2 Common Lispのシンボルは、もっといろいろ付加情報を持っている

*3 らしい