mokeheheのScheme日記

ツッコミ、添削大歓迎です。いろいろ教えてください。

2008-01-05

[] Practical Common Lisp第11章 コレクション

http://gigamonkeys.com/book/collections.html

  • Lispはリストだけじゃなくて、他の言語と同等に配列ハッシュも扱えるよ
  • vectorとlistは、より一般的な抽象化であるsequenceのサブクラスなので多くの共通点がある
vector
  • 固定サイズのvectorとリサイズ可能なvector
  • 固定:vector 関数で作成できる
  • より一般的な:make-array 固定も可変も作成可能、任意次元
  • :adjustable で実際にリサイズ可能に
vectorのサブタイプ
  • 文字列は要素がキャラクタに限定されたベクトルなので、次の章でベクトルを取る関数が文字列も受け取れることについて話す、とのこと。
  • make-array で、:element-type に 'character を与えれば、文字列が作れる
(make-array 5 :fill-pointer 0 :adjustable t :element-type 'character)  ;=> ""
シーケンスとしてのvector
シーケンスをなめる関数
  • いろんなキーワードで動作調整可能
    • たくさんあって複雑という気がせんでもない
高階関数の種類
シーケンス全体の操作


[] Practical Common Lisp第10章 数値、キャラクタ、文字列

[] Practical Common Lisp第9章 実践:ユニットテストフレームワークの作成

  • テスト結果は成功か失敗のどっちか
2つの最初の試み
  • 全部のテストをandでつなぐ
    • これだとどこで失敗したかわからない
  • 個々に成功するか失敗するかを出力させる
    • いちいち書くのがメンドイ、あと数が増えたら困る
リファクタリング
  • 個々の結果出力を1つの関数 report-result に変える
  • 成功したかどうかと式とで2回書かなきゃいけないのを、check マクロを使って手間を省く
戻り値の修正
  • report-result から戻り値を返すようにする
  • and マクロだと失敗した時点で処理を打ち切ってしまうので、打ち切らない combine-results マクロを作る
よりよいレポート結果
  • いくつかテストケースを組み合わて、増えすぎた場合に今のレポートだと多すぎて探すのが大変
  • グローバルにテスト名を保持する変数を作って、テストで設定し、結果表示する
抽象化あらわる
  • テストケースの関数名と、テストケース名で2回設定してるのがムダ
  • テスト関数だけど、それはあなたの心の中だけで、コードが特定のパターンにのっとっていること以外でテスト関数だとはわからない
  • 中途半端な抽象化はソフトウェア構築の安っぽいツールにしかならない
  • なぜなら中途半端な抽象化はパターンのマニフェストによってコードに表現されるので、大量のコードを複製する(メンテに問題が出る)ことで保障しなければならないからである
  • より微妙には、抽象化はプログラマの心の中だけにあるので、別のプログラマ(または未来の自分)に同じ抽象化を理解させる方法がないことである
  • 完璧な抽象化のためには、「これはテスト関数だ」ということを表現する方法と、パターンが必要とするすべてのコードが生成される必要がある
  • すなわちマクロ
  • deftest マクロを作る
テストの階層化
  • *test-name* をリストにすればいい
まとめる
  • 全部で26行!

Lispのリーダー

バッククォートとかカンマとかカンマアットとか、Lispのリーダーでどうやって処理してるんだろう?xyzzyでテスト:

(setf a 1234)
(setf ls '(1 2 3))

としておいて、展開形は

`(hello ,a)          ;=> (hello 1234)
`(hello ,a world)    ;=> (hello 1234 world)
`(hello ,ls world)   ;=> (hello (1 2 3) world)
`(hello ,@ls world)  ;=> (hello 1 2 3 world)

クォートをつけて、展開される前はどんなかをみると

'`(hello ,a)         ;=> (list 'hello a)
'`(hello ,a world)   ;=> (list* 'hello a '(world))
'`(hello ,ls world)  ;=> (list* 'hello ls '(world))
'`(hello ,@ls world) ;=> (cons 'hello (append ls '(world)))

うへぇ、場合分け多いな。

ryos36ryos362008/01/06 10:44えらい勢いで読んでますね。すばらしい。私は CH3, CH23,CH24,ch26 を斜め読み程度。う~ん。

mokehehemokehehe2008/01/06 12:43英文をかなり適当に読み飛ばしてますからね。
Peter Seibel氏の英文がわかりやすく、説明がうまいですね。
ryos36 さんはSchemeやLispをすでにご存知のようですので、
この本では簡単すぎるのではないですか? (^^;;

トラックバック - http://sicp.g.hatena.ne.jp/mokehehe/20080105