コーディングを支える技術


コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus)


技術評論社


著者:西尾泰和


はじめに
謝辞
本書の構成
 サンプルコードのダウンロード

第1章 言語を深く効率的に学ぶには
1.1 比較から学ぶ
決め事は言語によって異なる
C言語とRubyにおける真偽値
Javaにおける真偽値
1.2 歴史から学ぶ
言語設計者の意図を理解する
どの言語を学ぶべきかは誰にもわからない
言語に依存しない普遍的な知識を学ぶ
1.3 まとめ

第2章 プログラミング言語を俯瞰する
2.1 プログラミング言語誕生の歴史
ケーブルをつなぐ
プログラム内蔵方式へ
FORTRANの登場
2.2 プログラミング言語の生まれた目的
無精 ──プログラマの三大美徳の一つ
言語により異なる「楽さ」の意味
 何を楽にしたいのか
 どんなプログラムを書くのを楽にしたいのか
2.3 まとめ

第3章 文法の誕生
3.1 文法って何だろう?
演算子の優先順位
文法は言語設計者が決めたルール
3.2 スタックマシンとFORTH
計算の流れ
計算順序をどう表現する?
現代にも生きるスタックマシン
3.3 構文木とLISP
計算の流れ
計算順序をどう表現する?
現代にも生きる構文木
【Column】理解を確認するためにはまずアウトプット
3.4 中置記法
構文解析器
【Column】何を学べがよいかがわからない理由
ルールの競合
3.5 まとめ

第4章 処理の流れのコントロール
4.1 構造化プログラミングの誕生
4.2 ifが生まれる前
ifはなぜあるのか
if……elseはなぜあるのか
 アセンブリ言語での表現方法
 C言語での表現方法
 if……elseを使うメリット
4.3 while ──繰り返しのifを読みやすく表現
whileを使った表現方法
whileを使わない表現方法
4.4 for ──数値を増やしながらのwhileを読みやすく表現
forを使った表現方法
forを使わない表現方法
foreach ──処理の対象で繰り返しを制御
4.5 まとめ

第5章 関数
5.1 関数の役割
理解 ──組織のたとえ
再利用 ──部品のたとえ
プログラムにおける再利用の特徴
5.2 戻る命令
関数の誕生
戻る先を記録する専用のメモリ
【Column】名前
スタック
5.3 再帰呼び出し
入れ子構造のデータを効率的に処理
入れ子構造を扱う方法
forでは表現できない
再帰呼び出しを使う
再帰呼び出しの実行の流れ
5.4 まとめ

第6章 エラー処理
6.1 プログラムも失敗をする
6.2 失敗をどうやって伝える?
返り値で失敗を伝える
 失敗を見落とす
 エラー処理のせいでコードが読みづらい
 ジャンプでエラー処理をまとめる
失敗したらジャンプする
 UNIVAC Iの場合
 COBOLの場合
 PL/Iの場合
6.3 失敗しそうなコードを囲む構文
John Goodenoughの主張
CLUへの導入
C++への導入
Windows NT 3.1への導入
6.4 出口を1つにしたい
なぜfinallyを導入したのか
対になる処理を確実に行いたい
 finallyによる解決
 finallyのないC++での解決
 D言語のscope(exit)による解決
6.5 どういうときに例外を投げるか
関数呼び出し時に引数が不足している場合
配列の範囲外を取得しようとした場合
間違えたらすぐに例外を投げてほしい
6.6 例外の伝搬
例外が伝搬する問題点
Javaの検査例外
検査例外が普及しない理由
【Column】具体的な知識と抽象的な知識
【Column】噛み砕く
6.7 まとめ
【Column】必要なところからかじる

第7章 名前とスコープ
7.1 名前はなぜ必要だったか
どうやって名前を付けるか
名前の衝突
衝突を回避するには
 長い変数名を付ける
 スコープを利用する
7.2 スコープの進化
動的スコープ
 どのように動作するか
 問題点
静的スコープ
 動的スコープは対応表がコード全体から読める
 静的スコープは関数ごとに対応表を分ける
7.3 静的スコープは完成形?
【Column】ほかの言語でのスコープは?
ネストした関数の問題
外のスコープへの再束縛の問題
 Pythonでの解決方法
 Rubyでの解決方法
7.4 まとめ

第8章 型
8.1 型とは何か
8.2 数値をオンとオフで表現する方法
位取りの発明
7セグメントディスプレイ
そろばん
8.3 1つの位に必要なランプはいくつか?
10進法から2進法ヘ
8進法と16進法
 8進法
 16進法
8.4 実数はどうやって表現しよう
定小数点数──小数点がどこに付くか決める
浮動小数点数──どこからが小数部かの情報自体を値に含める
どのような考え方か
IEEE 754で定められた浮動小数点数のしくみ
問題点
8.5 型は何のため?
ないとどう困るのか
初期のFORTRANでの型
言語処理系に変数の種類を教える
暗黙の型昇格
 整数同士,浮動小数点数同士の演算
 片方が整数で片方が浮動小数点数の演算
 問題点
 書き方で区別する言語
8.6 型のいろいろな展開
ユーザ定義型とオブジェクト指向
仕様としての型
 公開と非公開を分ける
 インタフェースへの発展
 型ですべての仕様を表現する世界が来るか
総称型,ジェネリクス,テンプレート
 C++の場合
 Javaの場合
 Haskellの場合
動的型付け
 どのように実現しているか
 メリットとデメリット
型推論
 Haskellと型推論のないC言語の比較
 Haskellの型推論
 Scalaの型推論
 強い型でバグのないプログラムが作れるか
8.7 まとめ
【Column】おおまかにつかんで徐々に詳細化する

第9章 コンテナと文字列
9.1 いろいろな種類のコンテナがある
9.2 なぜいろいろな種類のコンテナがあるのか
配列と連結リスト
 配列に値を挿入する場合
 連結リストに値を挿入する場合
 連結リストの模式図
 連結リストの長所と短所
 【Column】O記法──計算時間とデータ量の関係を簡潔に表す
 言語による違い
9.3 辞書,ハッシュ,連想配列
ハッシュテーブル

要素を取り出す時間
 木の場合
 ハッシュテーブルの場合
万能のコンテナはない
9.4 文字とは何か
文字集合と文字符号化方式
コンピュータ以前の符号化
 モールス符号
 ボーコード
EDSACの文字コード
ASCIIとEBCDICの時代
日本語エンコーディング
 ISO-2022-JP
 Shift_JIS
 EUC-JP
Shift_JISがプログラムを壊す
マジックコメント
Unicodeによる統一
9.5 文字列とは何か
長さの情報を持つPascal文字列,持たないC文字列
 NUL文字で文字列の終わりを表現する
 NUL文字にまつわる不具合の例
1文字16bitのJava文字列
Python 3で行われた設計の変更
Ruby 1.9の挑戦
9.6 まとめ

第10章 並行処理
10.1 並行処理とは何か
10.2 細かく区切って実行する
10.3 処理を切り替える2通りの方法
協調的マルチタスク──切りの良いところで交代する
プリエンプティブマルチタスク── 一定時間で交代する
10.4 競合状態を防ぐには
競合状態の3条件
共有しない──プロセスとアクターモデル
 プロセスではメモリを共有しない
 共有しないアプローチは成功したか
アクターモデル
書き換えない──const,val,Immutable
割り込まない
 協調的なスレッドを使う──ファイバー,コルーチン,グリーンスレッド
 割り込まれると困る処理中は印を付ける──ロック,ミューテックス,セマフォ
10.5 ロックの問題点と解決策
ロックの問題点
 デッドロックが発生してしまう
 合成できない
トランザクショナルメモリによる解決
トランザクショナルメモリの歴史
 ハードウェアによる実装
 ソフトウェアによる実装
トランザクショナルメモリは成功するか
10.6 まとめ

第11章 オブジェクトとクラス
11.1 オブジェクト指向とは何か
言語によって違う「オブジェクト指向」の意味
オブジェクトは現実世界の模型
クラスとは
11.2 変数と関数を束ねて模型を作る方法
11.3 方法1 モジュール,パッケージ
モジュール,パッケージとは何か
Perlのパッケージでオブジェクトを作る
モジュールだけでは足りない
データ置き場は個別に
引数に個別のハッシュを渡す
初期化の処理もパッケージに入れる
ハッシュとパッケージを結び付ける
11.4 方法2 関数もハッシュに入れる
ファーストクラス
関数をハッシュに入れる
複数のカウンタを作る
共有してよいモノをプロトタイプに移す
 プロトタイプの動作
 new演算子で効率的に記述する
これがオブジェクト指向?
11.5 方法3 クロージャ
クロージャとは
なぜクロージャと呼ぶ?
11.6 方法4 クラス
Hoareの考えたクラス
C++のクラス
仕様としての役割
クラスが持つ3つの役割
11.7 まとめ

第12章 継承によるコードの再利用
12.1 継承とは
継承に対するさまざまな考え方
 一般化/特殊化
 共通部分の抽出
 差分実装
継承は諸刃の剣
リスコフの置換原則
12.2 多重継承
1つのモノを複数の分類に
実装の再利用に便利な多重継承
12.3 多重継承の問題点──またしても衝突!
解決策1 多重継承を禁止する
 委譲
 インタフェース
解決策2 メソッド解決順序を工夫する
 深さ優先探索の問題点
 C3線形化で順序を決める
解決策3 処理を混ぜ込む(Mix-in)
 Pythonの場合
 Rubyの場合
解決策4 トレイト
 名前が衝突したときの振る舞い
 提供するメソッドと要求するメソッド
 ほかにもいろいろな機能が……
 トレイトが広まりつつある
12.4 まとめ
【Column】端から順番に写経する

あとがき
索引

書籍目次

Posted by shi-n