カテゴリ:一人読書会( 17 )
On Lisp 第7章 マクロ
いよいよ本番。
マクロなんてほとんど使った事のないヘタレなので、話の内容が新鮮。

マクロ定義とは実質的にLispコードを生成する関数だ
-- つまりプログラムを書くプログラムだ。

7.1 マクロはどのように動作するか
- 関数 => 結果
マクロ => 式 => 結果

- マクロ呼び出し
1. 与えた定義の指定した式を生成
2. 生成した式を元のマクロ呼び出しの場所で評価する

7.2 バッククォート
- バッククォートは特別なクォート
(equal `(a b c) '(a b c))               ;=> T
(equal `(a b c) (list 'a 'b 'c)) ;=> T

- バッククォート内のカンマ => 評価の保護をやめる
(setq b 1
d 2)
(equal `(a ,b c ,d) (list 'a b 'c d))
;=> (equal `(a 1 c 2) (list 'a 1 'c 2))
;=> T

;; リストが入れ子でも機能する
`(a (,b c))
;=> (A (1 C))

- 1個のカンマは1個のバッククォートの効果を打ち消す
# やばい、だんだん混乱してきたw
`(a (`,b c))
;=> (A (B C))

- カンマアット (,@) は、一番外側の括弧を取り除いて挿入
(setq b '(1 2 3))
`(a ,b c)
;=> (A (1 2 3) C)
`(a ,@b c)
;=> (A 1 2 3 C)

- ,@ の制限事項
- シーケンス内になければいけない
- 切り貼りされるオブジェクトは、最後に来ない限りリストでなければならない
(setq b 1)
`(a ,@b)
;=> (A . 1)
`(a ,@b c)
;=> ERROR!!


7.4 マクロ展開の確認
- macroexpand, マクロ展開関数
- macroexpand-1, マクロを一段階だけ展開
=> タイプ数節約のため、代わりにこんなマクロを定義
(defmacro mac (expr)
`(pprint (macroexpand-1 ',expr)))

- マクロ展開は、マクロの書き方の勉強手段でもある。
=> マクロの展開形を見て、どう書かれたのかを調べる。

7.7 プログラムとしてのマクロ
- マクロ展開では、gensym の返す特別な無名シンボルを使う

7.8 マクロのスタイル
- マクロ定義に関わる二種類のコード
- 展開コード => 明確さ優先
- 被展開コード => 効率優先

7.9 マクロへの依存
- 1. マクロはそれを呼び出す関数 (またはマクロ) の前で定義する。
2. マクロが再定義されたときは、
それを (直接または間接的に) 呼び出している関数とマクロを
すべて再コンパイルする


On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-11-10 23:55 | 一人読書会
On Lisp 第6章 表現としての関数
短い章。これからはじまるマクロ祭りへの序章っぽい。
初めてクロージャってものに触れたときはチンプンカンプンだったなぁ。

Lisp での表現手段 => クロージャ

6.1 ネットワーク
- クロージャの3つの便利な性質
- アクティブ
- ローカルな状態を保持している
- 複数のインスタンスを作れる

6.3 展望
- 「クロージャで表現する」==「コンパイルする」


On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-11-09 23:55 | 一人読書会
On Lisp 第5章 返り値としての関数
この辺りの関数指向の機能は、最近のプログラミング言語だと普通に持ってたりするところに、少し時代を感じる。
再帰の一般化のあたりは、少し歯ごたえがあって面白かった。


5.4 関数を合成する

5.5 cdr部での再帰
- スペシャル変数 *print-circle*
=> 印字中に同一のコンスまたは同一のベクタが現れるかかどうかを検出するか
# 循環リストを表示する場合等に設定
参考:
- データの入出力
- M.Hiroi's Home Page / xyzzy Lisp Programming

5.6 部分ツリーでの再帰
- copy-list, 部分リストの参照はそのまま
# shallow copy的なコピー
- copy-tree, 部分リストの構造を含めてコピー
# deep copy的なコピー

5.7 いつ関数を作るべきか
- リードマクロ #. で、ソース読み込み時に関数を生成

On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-11-06 23:55 | 一人読書会
On Lisp 第4章 ユーティリティ関数
&key とか :key みたいな、記号 + 一般的な名詞ってのは調べにくいなぁ。


- Common Lisp のオペーレータ
- 関数
- マクロ
- 特殊形式

4.1 ユーティリティの誕生
- 抽象化の初歩: 「振る舞いを密接に組み込んでは行けない」

4.4 検索
# 本書の直接の内容ではないけど、、、
- ラムダリストキーワード (参考:M.Hiroi's Home Page / xyzzy Lisp Programming)
- &key, キーワードを設定する
- :key, キーワードの指定
(defun before (x y lst &key (test #'eql))
(and lst
(let ((first (car lst)))
(cond ((funcall test y first) nil)
((funcall test x first) lst)
(t (before x y (cdr lst) :test test))))))

(before 'a 'b '(a b c d)) ;=> (A B C D)

を、&key を使わずに書き換えると
(defun before-no-key (x y lst)
(and lst
(let ((first (car lst)))
(cond ((eql y first) nil)
((eql x first) lst)
(t (before-no-key x y (cdr lst)))))))

(before-no-key 'a 'b '(a b c d)) ;=> (A B C D)


4.7 シンボルと文字列
- 任意の文字列をシンボルとして使用可能。
シンボルに空白や括弧が含まれる場合は、
「縦棒 (|) で挟まれる」 or 「文字の前に \ がつけられる」
(let ((s (symb '(a b))))
(and (eq s '|(A B)|) (eq s '\(A\ B\))))
;=> T




On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-11-05 23:55 | 一人読書会
On Lisp 第3章 関数プログラミング
まだまだ基礎の確認。


3.1 関数型のデザイン
- 副作用を避ける

- nconc
(setq x '(1 2 3))
(setq y '(4 5 6))
(nconc x y)
;=> x: (1 2 3 4 5 6)
; y: (4 5 6)

;; x が nil の時の挙動
(setq x nil)
(nconc x y)
;=> x: NIL
; y: (4, 5, 6)


- 多値の受け取り
(multiple-value-bind (int frac) (truncate 26.21875)
(list int frac))


- 多値を返すには values オペレータで
(defun powers (x)
(values x (sqrt x) (expt x 2)))



On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-10-31 23:55 | 一人読書会
On Lisp 第2章 関数
まだ小手調べ。Common Lisp の紹介といったところ。
といいつつ、Common Lisp と Scheme は、異なる部分が結構多いので、少し戸惑い中。


2.1 データとしての関数
- 関数は Lisp のオブジェクト

2.2 関数の定義
- #' オペレータ
=> 指定した名前の関数オブジェクトを取得

- 変数と関数の名前空間が別

2.4 属性としての関数
(defun behave (animal)
(funcall (get animal 'behavior)))

(setf (get 'dog 'behavior)
#'(lambda ()
(wag-tail)
(bark)))

(behave 'dog) ;;=> wag-tail と bark を実行

- OOP のメソッドの概念に対応

2.5 スコープ
- Common Lisp はレキシカルスコープ

2.7 ローカル関数
- labels 式
=> - ローカルに束縛された関数を作る
- let と違い、labels 式の中で定義された関数を参照可能
(defun count-instances (obj lsts)
(labels ((instances-in (lst)
(if (consp lst)
(+ (if (eq (car lst) obj) 1 0)
(instances-in (cdr lst)))
0)))
(mapcar #'instances-in lsts)))

# defun の中に defun じゃだめなの?
# とおもったら、defun は宣言する場所に関係なく、
# グローバルスコープに関数を定義してしまうらしい。
# flet と labels の動作確認 - ポロポロ

2.8 末尾再帰
- 末尾再帰を最適化するかどうかは、実装依存
# CLISP はそのままでは最適化しない
# => (proclaim '(optimize speed)) が必要

2.9 コンパイル
- (compiled-function-p #'foo)
# コンパイルされているかどうかの判定

- 関数単位のコンパイル
- (compile 'foo)
- (compile nil '(lambda (x) (+ x 2)))
# compile を陽に呼ぶのは、eval を呼ぶのに匹敵するほど過激な方法

- ファイル単位のコンパイル
- compile-file


On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools
[PR]
by fkmn | 2009-10-28 23:55 | 一人読書会
【一人読書会目次】On Lisp
On Lisp
Paul Graham

4274066371
オーム社 2007-03
売り上げランキング : 82240
おすすめ平均 star

Amazonで詳しく見る
by G-Tools


[PR]
by fkmn | 2001-01-01 00:00 | 一人読書会


とあるWebアプリケーションエンジニアの日記
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
カテゴリ
以前の記事
ブログパーツ
リンク
検索
タグ
最新のトラックバック
プログラミングが「出来る..
from とりあえず9JP?
Genographic ..
from ナンジャモンジャ
ジュセリーノ
from ありの出来事
くちこみブログ集(ライフ..
from くちこみブログ集(ライフ)(..
以降、丁寧語で行こう!
from エッセイ的な何か
その他のジャンル
ファン
記事ランキング
ブログジャンル
画像一覧

fkmnの最近読んだ本 フィードメーター - フッ君の日常 あわせて読みたい AX