実践Common Lispを読む 第30章〜第32章 読了
こんにちは。今回で「実践Common Lispを読む」は最後になります。
第30章 実践:HTML生成ライブラリ インタプリタ版
FOOは、関数やクラスやマクロから構成されるAPIではなく、CommonLispプログラムに組み込み可能な特定用途向け言語を処理する言語プロセッサを提供する
いわば言語指向のプログラミングらしい?
lolにあったドメイン特化言語(DSL) とは同じっぽい
FOOでは2つの言語プロセッサを提供している。1つはHTMLを生成するためにFOOの「プログラム」をデータとして受け取り、解釈するインタプリタ。
もうひとつは場合によってはCommonLispのコードが組み込まれているFOOの式を受け取り、そこからHTMLを生成してコードを実行するコンパイラ。
前者はemit-htmlで、後者はhtmlマクロ。
*特定用途向け言語の設計
組み込み言語の設計には
- 表現したいと考えている内容を記述できる
- 「プログラム」を受け取って、指示された動作を実行するか、同等の動作をするCommonLispのコードに変換する
というプロセスが必要
その時には表現力と簡潔さのバランスが求められる
*FOO言語
もっとも単純なFOOフォームは自己評価型のLispオブジェクト(文字列、数字、キーワードシンボル)
属性ってのがなんのためにあるのかわからんけどリストのシンボルの直後におくか、リストのRESTによって表現するかの2通りがある。
このシンタックスの違いを抽象化したいなら、HMTLタグ、属性リスト、本体の3つにパースする関数parse-cons-formを定義すればいい
ひとまずインタプリタでもコンパイルでも、いい感じにインデントされた出力が欲しいだろうから、それを先につくる
*文字のエスケープ
「<>&'"」あたりを「<」や「>」とかに置き換えていきたい。
そのためにescape-charとescape関数で実現する
*インデントプリンタ
出力ストリームをラップしたindenting-printerクラスを定義する
改行とか文字列の出力とかを実現するためのemit関数等を定義
*HTMLプロセッサインターフェース
2つの実装のための総称関数を定義
*基本的な評価のルール
あるオブジェクトを受けてHTMLを生成するための適切な処理や実行する関数が必要
FOOフォームか否かを判定してprocess-sexp-html関数に引き渡す関数を定義。
...割愛
第31章 実践:HTML生成ライブラリ コンパイラ版
コンパイラとインタプリタの主な違いは、インタプリタがプログラムを処理して直接動作するのに対し、コンパイラは同じプログラムを処理することで同じ振る舞いを示す別の言語のコードを生成する点。
逐一コードを読む気にもならず、さらっと流し読みしてしまった・・・
ちゃんとHTMLを生成出来るようになったし、特殊オペレータも使えるようになった。(
EVAL-WHENオペレータは本体のコードによって引き起こされる効果がCOMPLILE-FIELを使ってコンパイルされている間にのみ可視状態になることを保証するもの。)
マクロも書ける。
「終わりに」の所で組み込みJavaScriptの生成のサポートをすることについて触れられているのはすごいことじゃないですか?
第32章 結論:さて次は?
自分でLispについて学ぶためのtips
ライブラリ探し
- Common-Lisp.net (http://www.common-lisp.net/)
- The Common Lisp Open Code Collection (CLOCC) (http://clocc.sourceforge.net/)
- Cliki (http://www.cliki.net/)
とりあえず動くから正しく速くへ
「早計な最適化は諸悪の根源」
CommonLispは遅くない。
速くするには、timeマクロを使ってチューニングすべきボトルネックを探すか、アルゴリズムを変えるかを考えるべきだけど、コードバミング(余計なことは一切しないコード、コード狂い)に陥るかもしれない。DISASSEMBLE関数を使うとコードをアセンブリ言語風にダンプしてくれるから、無駄が分かるかも。
CL-USER> (defun add (x y) (+ x y)) ADD CL-USER> (disassemble 'add) ; disassembly for ADD ; Size: 28 bytes ; 05B811FD: 488B55F8 MOV RDX, [RBP-8] ; no-arg-parsing entry point ; 201: 488B7DF0 MOV RDI, [RBP-16] ; 205: 41BBF0010020 MOV R11D, 536871408 ; GENERIC-+ ; 20B: 41FFD3 CALL R11 ; 20E: 488BE5 MOV RSP, RBP ; 211: F8 CLC ; 212: 5D POP RBP ; 213: C3 RET ; 214: CC0A BREAK 10 ; error trap ; 216: 02 BYTE #X02 ; 217: 19 BYTE #X19 ; INVALID-ARG-COU NT-ERROR ; 218: 9A BYTE #X9A ; RCX NIL
アプリケーションの配布
ソースファイルをloadするか、システム定義ツールASDFを使うといい。
エンドユーザ向けには、WindowsのDLLのような形式がない。Lispにはプログラミングのきちんとした定義がないからだ。使っているものによって解決策は色々あるっぽい。
次のステージ
ぜひいますぐ自分のLispコードを書き始めて欲しい
Lisperと触れ合うなら
- Usentのcomp.lang.lisp(https://groups.google.com/forum/#!forum/comp.lang.lisp)
- IRCチャンネルかFreenodeネットワークの#lisp(http://www.cliki.net/IRC)
- Lisp関連のブログはPlanet Lisp(http://planet.lisp.org/)
書籍
リファレンス
- David Margolies:"The ANSI Common Lisp Reference Book"
オブジェクトシステム
- Sonya Keene:"Object-Oriented Programming in Common Lisp
オブジェクトウィザードになる、頭の体操
- G.Kiczales,Jim des R.,D.G. Bobrow:"The Art of the Metaobject Protocol"
Common Lispについて
- Peter Norvig:"Paradigms of Artificial Intelligence Programming:Case Studies in Common Lisp"
- Paul Graham:"On Lisp"
ビットレベルの動作
- Christian Queinnec:"Lisp in Small Pieces"
理論的なの
その他もろもろ
元の本をぐぐってたら、OnlineProgrammingBooks.comっていうサイトに行き着いた。
Common Lispの本で名前を見たことがあるやつはだいたいある。英語だけど・・・
http://www.onlineprogrammingbooks.com/lisp/
「言語を本当に身につける唯一の方法は使ってみることだ。ここまで来たのなら、もちろんその準備はできている。それでは、Happy hacking!」
全体の感想
この本を読み始めてから、早いもので2か月以上が経ちました。2か月前に比べてコードがスラスラ読めて書けるようになったかといえば残念ながらそんなことはありません。わからないまま読み飛ばしたところもかなりそのままになっています。特に後半の実践の章に入ってからはコードを追うのも辛く、大抵コードをそのまま読むことはせずに解説の文章ばかりを目で追っていました。それでも、Emacs+SLIMEを抵抗なく使うようになってきたし、いくつか面白いコードに出会ったりしたのでまったく無駄だったわけではないと思います。前回読んでいたLand of Lispとはまた違った方向の本でした。パッケージを使って大規模なアプリケーションを構築していくのはそれこそ「実践」だったと思います。Common Lispはなんでもできるんや!と思い知らされました。
今回で、Common Lispに関する本は2冊目です。本を読むとき以外は全くプログラミングをしていないので、そろそろ自分で何かを作ってみたいなと思い始めています。思うだけで終わらなければいいですが・・・。
あと、この本を借りるときに一緒に借りてきた「関数プログラミング実践入門」という本を暇なときに眺めていたのですが、どうやらHaskellという言語の本らしいです。この本でも言及されているように、Common Lispは純粋な関数型言語ではないことは実践Common Lispでも最初のほうに書かれていたことです。それに対して、Haskellはとても純粋な関数型言語らしく、また謎の世界を垣間見てしまいそうだなと思っています。これはコードを動かしたりせずに適当に流し読みするつもりです。
今後は、ひとまず自分でいろいろ書いてみたいなと思っています。Common Lispについての情報を何となくRedittやQiitaで読んでみたりしているので、そのソースを読んだりもしています。それでもうちょいステップアップしたいなーと思ったらOn Lispを読んだりすると思います。たぶん。でも10月に応用情報受けるんで勉強しないとなとか、ドン・キホーテの後編を読まないとなーとかジムでムキムキになりたいなーとか思っているので、プログラミングをする時間があるかは微妙です。
最後らへんは飛ばし気味だったので記事としてほぼ価値がありませんが、「実践Common Lispを読む」は今回で終了になります。ありがとうございました。lolと同じように、またいつか読み直したいです。