謝辞 はじめに Lispがクールで、そして奇妙なわけ Lispがそんなにすごいなら、どうしてもっとたくさん使われないのか Lispはどこから来たのか Lispの力はどこから来るのか 第I部 LISPは力なり 1章 さあLispを始めてみよう 1.1 Lispの方言 二つのLispの物語 新しいLispたち スクリプティングに使われるLisp方言 ANSI Common Lisp 1.2 CLISPを始めよう CLISPのインストール CLISPを起動する 1.3 この章で学んだこと 2章 はじめてのLispプログラム 2.1 数当てゲーム 2.2 Lispでグローバル変数を定義する 変数smallとbigを定義する グローバル変数を定義するもう一つの方法 2.3 基本的なLispのエチケット 2.4 グローバル関数を定義する guess-my-number関数の定義 smallerとbigger関数の定義 start-over関数の定義 2.5 ローカル変数を定義する 2.6 ローカル関数の定義 2.7 本章で学んだこと 3章 Lispの構文の世界を探検する 3.1 シンタックスとセマンティクス 3.2 Lispシンタックスの構成要素 シンボル 数値 文字列 3.3 Lispはコードとデータをどう区別するか コードモード データモード 3.4 Lispとリスト コンスセル リストを扱う関数 ネストしたリスト 3.5 本章で学んだこと 第II部 LISPは対称なり 4章 条件と判断 4.1 nilと()の対称性 空とは偽なり ()の四つの顔 4.2 条件分岐: Ifとその仲間たち ifは一度に一つずつ ifを越えて: whenとunless 万能条件コマンドcond caseによる分岐 4.3 ちょっとした条件式のテクニック 隠された条件分岐、andとorを使う 真理以上のものを返す関数 4.4 比較関数: eq、equal、そしてもっと 4.5 本章で学んだこと 5章 テキストゲームのエンジンを作る 5.1 魔法使いのアドベンチャー このゲームの世界 基本的な要求仕様 連想リストを使って景色を描写する 情景を描写する 5.2 通り道を描写する 準クオートの仕組み 複数の通り道を一度に描写する 5.3 特定の場所にあるオブジェクトを描写する 目に見えるオブジェクトをリストする 見えるオブジェクトを描写する 5.4 全てを描写する 5.5 ゲーム世界を動き回る 5.6 オブジェクトを手に取る 5.7 持っているものを調べる 5.8 本章で学んだこと 6章 世界とのインタフェース: Lispでのデータの読み書き 6.1 テキストの表示と読み込み スクリーンへの表示 ユーザに挨拶しよう printとreadから始める 人に優しいデータの読み書き 6.2 Lispにおけるコードとデータの対称性 6.3 ゲームエンジンに専用のインタフェースを追加する 専用のREPLの準備 専用のread関数を書く game-eval関数を書く game-print関数を書く 6.4 さあこの素敵なゲームインタフェースを試してみよう 6.5 readとevalの危険について 6.6 本章で学んだこと 6.5章 lambda：とても大事な関数なので特別に章を分けて説明しよう 6.5.1 lambdaがすること 6.5.2 lambdaがそんなに大事なわけ 6.5.3 本章で学んだこと 7章 単純なリストの先へ 7.1 奇妙なリスト ドットリスト 対 循環リスト 連想リスト 7.2 複雑なデータを扱うには 木構造のデータの可視化 グラフを可視化する 7.3 グラフを作る DOTの情報を生成する DOTファイルを画像にする グラフを画像にする 7.4 無向グラフを作る 7.5 本章で学んだこと 8章 親父のワンプスとは一味違う 8.1 グランド・セフト・ワンプス 8.2 コンジェスチョン・シティのエッジを定義する ランダムなエッジの生成 loopコマンドでループしよう 孤島を作らない コンジェスチョン・シティのためのエッジリストを完成させる 8.3 コンジェスチョン・シティのノードリストを作る 8.4 新しいゲームを始めるために、グランド・セフト・ワンプスを初期化する 8.5 シティのマップを描く 部分的な知識からシティを描く 既知の部分だけの地図を描く 街を歩き回る 8.6 ワンプスを狩り出せ! 8.7 本章で学んだこと 9章 より進んだデータ型とジェネリックプログラミング 9.1 配列 配列を使う ジェネリックなセッター 配列とリスト 9.2 ハッシュテーブル ハッシュテーブルを使う 複数の値を返す ハッシュテーブルの性能 グランド・セフト・ワンプスの性能をハッシュテーブルで改善する 9.3 構造体 構造体を使う 構造体をいつ使うか 9.4 データをジェネリックに扱う シーケンスを使う 型述語を使って自分でジェネリック関数を作る 9.5 オーク・バトル プレーヤーとモンスターのグローバル変数 ゲームのメイン関数 プレーヤーを管理する関数 プレーヤーの攻撃に使う補助関数 モンスターを管理する関数 モンスターたち 戦いだ! 9.6 本章で学んだこと 第III部 LISPはハックなり loopとformat: Lispの怪しげな下町 10章 loopコマンドによるループ 10.1 loopマクロ loopの使用例 loopマクロの全てを知る 10.2 loopを使って進化ゲームを作ろう マップに草を生やそう シミュレーション世界の1日 世界を描く ユーザインタフェースを作る 進化の様子をみてみよう 進化の種明かし 10.3 本章で学んだこと 11章 format関数でテキストを表示する 11.1 format関数の呼び出し方 出力先 制御文字列 値引数 11.2 Lispの値を表示する制御シーケンス 11.3 数値を整形する制御シーケンス 整数の整形 浮動小数点数の整形 11.4 複数行出力 11.5 テキストを揃える 11.6 繰り返しの制御シーケンス 11.7 綺麗な表を作るクレージーな整形トリック 11.8 ロボットの襲撃! 11.9 本章で学んだこと 12章 ストリーム 12.1 ストリームの種類 リソースの種類による分類 向きによる分類 12.2 ファイルの読み書き 12.3 ソケットを使う ソケットアドレス コネクション ソケット上でメッセージを送る 遊んだ後はお片付け 12.4 異端児の文字列ストリーム 関数にストリームを渡す 長い文字列を作る コードの読みやすさとデバッグ 12.5 本章で学んだこと 13章 Webサーバを作ろう! 13.1 Common Lispでのエラー処理 コンディションを通知する 自前のコンディションを作る コンディションを横取りする 予想外のコンディションからリソースを保護する 13.2 ゼロからWebサーバを書く Webサーバの仕組み リクエストパラメータ リクエストヘッダを解析する 文字列ストリームを使ってget-headerをテストする リクエストボディの解析 最後の仕上げのサーバ関数 13.3 動的なWebサイトを作る リクエストハンドラをテストする Webサイトの立ち上げ 13.4 本章で学んだこと 13.5章 美しき哉 関数型プログラミング 第IV部 LISPは科学なり 14章 関数型プログラミングでLispをレベルアップ 14.1 関数型プログラミングって何だ? 14.2 関数型スタイルで書かれたプログラムの分析 14.3 高階プログラミング 命令型コードでのコード合成 関数型スタイルを使う 高階プログラミングによる救援 14.4 関数型プログラミングはなぜクレージーか 14.5 関数型プログラミングはなぜ素晴らしいか 関数型プログラミングはバグを減らす 関数型プログラミングは簡潔だ 関数型プログラミングはエレガントだ 14.6 本章で学んだこと 15章 ダイス・オブ・ドゥーム：関数型スタイルでゲームを書こう 15.1 ダイス・オブ・ドゥームのルール 15.2 ダイス・オブ・ドゥームのゲーム例 15.3 ダイス・オブ・ドゥームの実装、バージョン1 いくつかのグローバル変数 ゲーム盤の表現 ダイス・オブ・ドゥームのルールをゲームの他の部分から分離する ゲームツリーの生成 相手に手番を渡す 攻撃の手を計算する 隣接するマスを見つける 攻撃 補給 game-tree関数を試す 人間対人間でダイス・オブ・ドゥームをプレイする 15.4 コンピュータによる対戦相手を作る ミニマックスアルゴリズム ミニマックスをコードにする AIプレーヤーを使うゲームループ 人間対コンピュータで対戦してみよう 15.5 ダイス・オブ・ドゥームを高速化する クロージャ メモ化 末尾呼び出し最適化 3x3のゲーム盤でのプレイ例 15.6 本章で学んだこと 16章 マクロの魔法 16.1 簡単なLispマクロ マクロの展開 マクロはどんなふうに変換されるか 簡単なマクロを使ってみる 16.2 もっと複雑なマクロ リストを分割するマクロ マクロ中で式が繰り返し実行されるのを防ぐ 変数捕捉を避ける 再帰呼び出しマクロ 16.3 マクロの危険と代替案 16.4 本章で学んだこと 17章 ドメイン特化言語 17.1 ドメインとは何か 17.2 SVGファイルを書き出す タグマクロを使ってXMLとHTMLを生成する SVG特有のマクロと関数を作る もっと複雑なSVG画像を描く 17.3 魔法使いのアドベンチャーゲームに新たなコマンドを追加する ゲームコマンドを直接定義する 完成した魔法使いのアドベンチャーゲームをプレーしよう 17.4 本章で学んだこと 18章 遅延プログラミング 18.1 Lispに遅延評価を足す lazyコマンドとforceコマンドの作成 遅延リストライブラリを作る 通常のリストと遅延リストとの変換 遅延リストに対するマッピングと検索 18.2 ダイス・オブ・ドゥーム、バージョン2 18.3 大きなゲーム盤でAIを動かす ゲーム木の刈り込み ヒューリスティクスを適用する 大きく勝つか小さく勝つか アルファ・ベータ法 18.4 本章で学んだこと 19章 ダイス・オブ・ドゥームに グラフィカルなWebインタフェースをつける 19.1 ゲーム盤をSVGフォーマットで描画する サイコロを描く マスを描く ゲーム盤を描く 19.2 Webサーバインタフェースを作る リクエストハンドラの作成 このゲームWebサーバの制限 ゲームを初期化する 勝者を表示する 人間のプレーヤーの処理 コンピュータプレーヤーを処理する HTMLの中にSVGゲーム盤を描く 19.3 ダイス・オブ・ドゥーム、バージョン3をプレーする 19.4 本章で学んだこと 20章 ダイス・オブ・ドゥームをさらに面白く 20.1 プレーヤーの数を増やす 20.2 サイコロを振る 確率ノードを作る サイコロを実際に振る ゲームエンジンからサイコロを振るコードを呼び出す AIの改良 20.3 ダイス・オブ・ドゥームの補給ルールの改善 20.4 終わりに エピローグ 訳者あとがき 索引