contents memorandum はてな

目次とメモを置いとく場

『コーディングを支える技術――成り立ちから学ぶプログラミング作法』(西尾泰和 技術評論社 2013)

著者:西尾 泰和[にしお・ひろかず](1981-) ソフトウェア・エンジニア。
シリーズ:WEB+DB PRESS plus


「コーディングを支える技術」著者公式ページ
コーディングを支える技術 著者公式ページ - 西尾泰和のScrapbox
コーディングを支える技術――成り立ちから学ぶプログラミング作法:書籍案内|技術評論社


【目次】
但し書き [ii]
はじめに [iii]
謝辞(2013年3月 西尾泰和) [iv]
本書の構成 [v]
サンプルコードのダウンロード [vi]
目次 [vii-xvi]


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


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


第3章:文法の誕生 015
3.1 文法って何だろう? 016
  演算子の優先順位
  文法は言語設計者が決めたルール
3.2 スタックマシンとFORTH 018
  計算の流れ
  計算順序をどう表現する?
  現代にも生きるスタックマシン
3.3 構文木LISP 021
  計算の流れ
  計算順序をどう表現する?
  現代にも生きる構文木
3.4 中置記法 025
  構文解析
  ルールの競合
3.5 まとめ 028

Column 理解を確認するためにはまずアウトプット 023
Column 何を学べがよいかがわからない理由 026


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


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

Column 名前 047


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

Column 具体的な知識と抽象的な知識 079
Column 噛み砕く 080
Column 必要なところからかじる 082


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

Column ほかの言語でのスコープは? 095


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

Column おおまかにつかんで徐々に詳細化する 134


第9章:コンテナと文字列 135
9.1 いろいろな種類のコンテナがある 136
9.2 なぜいろいろな種類のコンテナがあるのか 137
  配列と連結リスト
    配列に値を挿入する場合
    連結リストに値を挿入する場合
    連結リストの模式図
  連結リストの長所と短所
  言語による違い
9.3 辞書,ハッシュ,連想配列 143
  ハッシュテーブル
  木
  要素を取り出す時間
    木の場合
    ハッシュテーブルの場合
  万能のコンテナはない
9.4 文字とは何か 150
  文字集合文字符号化方式
  コンピュータ以前の符号化
    モールス符号
    ボーコード
  EDSACの文字コード
  ASCIIとEBCDICの時代
  日本語エンコーディング
    ISO-2022-JP
    Shift_JIS
    EUC-JP
  Shift_JISがプログラムを壊す
  マジックコメント
  Unicodeによる統一
9.5 文字列とは何か 162
  長さの情報を持つPascal文字列,持たないC文字列
    NUL文字で文字列の終わりを表現する
    NUL文字にまつわる不具合の例
  1文字16bitのJava文字列
  Python 3で行われた設計の変更
  Ruby 1.9の挑戦 
9.6 まとめ 168

Column O記法――計算時間とデータ量の関係を簡潔に表す 141


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


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


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

Column 端から順番に写経する 235


あとがき [236-237]
索引 [238-246]
著者略歴 [247]