誤:「ほかにもPythonは0が偽ですが、さらに「サイズが0のコンテナも偽」と定義されていて、空文字列や空リストも偽です。C言語のchar*は空でも偽になりません。」
正:「数値以外のことも考えてみましょう。Pythonでは0が偽で、さらに「サイズが0のコンテナも偽」と定義されています。なので、空文字列や空リストも偽です。C言語で文字列を扱うときに使われるchar*は、空文字列を指していても偽にはなりません。何も指していない(値がNULL)のときに偽になります。」
補足説明:「char*が空」という表現は適切ではないので修正しました。
誤「"Punched tape" Wikipedia: The Free Encyclopedia. Wikimedia Foundation, Inc. 2012年1月8日22時(日本時間)現在での最新版を取得。URL:http://en.wikipedia.org/」
正「"Punched tape" by TedColes. 2012年1月8日22時(日本時間)現在での最新版を取得。URL:http://en.wikipedia.org/wiki/File:PaperTapes-5and8Hole.jpg」
誤:「これをそれぞれ後置記法、前置記法、中置記法と呼びます」
正:「このように演算子を演算対象の後ろに置く記法を後置記法、前に置く記法を前置記法、間に置く記法を中置記法と呼びます」
脚注の追加:「前置記法に括弧は必須ではありません。「+や*が2個の演算対象を取る」とわかっているなら、括弧を省いて * + 1 2 3 と書いても意図がわかります。LISPでは、演算対象が3つ以上でも (+ 1 2 3 4) と書くことができます。これは括弧があるおかげですし、逆に括弧を省くことができない原因でもあります。」
補足説明:p.25の前置記法の説明では(+ 1 2)が前置記法だと書いていますが、この書き方では括弧も含めて前置記法であるように勘違いをさせてしまう可能性があります。そこで上記のように修正しました。
脚注の追加:「1949年に書かれたThe Square Programでは、92番地および114番地で、75番地に置かれたジャンプ命令のジャンプ先を書き換えています。ここではこのテクニックを簡略化して説明しています。こちらのPDFで実際のソースコードと解説を見ることができます: http://www.cl.cam.ac.uk/~mr10/edsacposter.pdf」
補足説明:ここではEDSACでのちに使われるようになる関数呼び出しの方法「Wheelerリンケージ」ではなく、1949年に作られたプログラムの中で使われている技法を説明しています。EDSACができたのが1949年の5月、このプログラムが書かれたのが1949年6月です。コードの再利用のために使われた最古のテクニックだと考えています。EDSAC上でのちに発明された、もっと洗練された関数呼び出しの仕組みについては和田英一先生のブログ記事「パラメトロン計算機: EDSACのプログラム技法」を参照下さい。
誤:ソースコード中の「!shippai()」
正:「shippai()」
削除:ソースコード下の「C言語に不慣れな人のために〜」
補足説明:今回の例では、「shippaiは成功したときに0(つまり偽)を返す」という仕様なので、つまり「失敗したときは真」なのですから「shippai()」を条件式とするのが適切でした。なお、ここでの例は「成功したときには0を返すのが一般的」という誤解を招くかもしれないのでもっと補足を入れたほうが良いかもしれないですね。たとえばfprintfは「書き込んだバイト数を返す、エラー時は負の数を返す」という仕様なので、shippaiが同じ仕様なら「shippai() < 0」とする必要があります。また、たとえばmallocは「成功したら確保した領域へのポインタを、失敗したらNULLを返す」という仕様なので、shippaiが同じ仕様なら「!shippai()」とする必要があります。
修正前:たとえば、失敗し得る処理を3つ実行したいとしましょう。たとえば、「shippai("A")をして、shippai("B")をして、shippai("C")をする」だとします。でも、shippai関数が失敗するかもしれないので、次のようなコードになってしまいます。
修正後:失敗し得る処理3つを実行して、もしどこかで失敗したならそれ以降の処理は行わずにエラー処理をしたいとしましょう。3つの処理はそれぞれshippai("A")、shippai("B")、shippai("C")とします。これは次のようなコードになります。
補足説明:修正前の説明では「Aの実行が失敗したときにBが実行されない」という仕様が伝わりません。そのため直後のコードでelse ifが使われている意図がわからず、混乱させてしまうので修正しました。
CLUに脚注の追加:「CLUの作者はオブジェクト指向設計の「リスコフの置換原則」にも名前の出てくるBarbara Liskovです。詳しくは216ページを参照してください。」
補足説明:例外処理の文脈でCLUという言語が出てきますが、このCLUを設計したのはオブジェクト指向のところでも名前の出てくるLiskovです。脚注で補足しようと思っていたのですが忘れました。
変更前:「一方 1990 年ごろ、Microsoft は C 言語で 32bit の Windows を作っていました。1993年にリリースされるWindows NT 3.1です。彼らも同じように、扱いやすいエラー処理のしくみが必要だと考えました。そして「構造化例外」(Structured Exception Handling、SEH)を導入しました。」
変更後:「一方 1990 年ごろ、Microsoft は C 言語で新しいOSを作っていました。1993年にリリースされるWindows NT 3.1です。彼らも同じように「扱いやすいエラー処理のしくみが必要だ」と考え、自分たちのOSとCコンパイラに「構造化例外」(Structured Exception Handling、SEH)という機能を追加しました。」
補足説明:「何にSEHを導入したのか」が書かれておらず「C言語の規格を拡張した」や「Visual C++を拡張した」という誤解の原因になるため補足しました。
変更前:「構造化例外には __tryと __except のほかに __finally というキーワードがありました。__finally とは何でしょうか? 次の節では finally がなぜ必要とされたかを学ぶことにしましょう。
変更後:「構造化例外には 失敗しそうなコードを囲む __try と エラー処理のコードを囲む __except のほかに、「__tryの中で失敗しても必ず実行したいコード」を囲む __finally がありました。この「必ず実行する記法」を、のちの言語での呼び方に合わせて今後は finally と呼ぶことにしましょう。次の節ではなぜ「必ず実行する記法」が必要とされたかを学びます。」
補足説明:「__finally とは何でしょうか」と書いているのに、「__finallyが何であるか」は説明されないまま、finallyの挙動だけが説明されていました。また、説明なくfinallyが出てくるので、__finallyとfinallyが同じものなのか違うものなのか、読者の混乱のもとになると考えました。
誤:tryはキーワードはまったく不必要
正:tryキーワードはまったく不必要
誤:そのメソッドを呼んでいるすべてのメソッドを修正なければならなくなったり
正:そのメソッドを呼んでいるすべてのメソッドを修正しなければならなくなったり
修正前:グローバル変数は書き換えるたびにその影響がプログラム全体に影響します。
修正後:グローバル変数を書き換えると、プログラム全体に影響します。
誤:「動的スコープは、グローバルスコープがない状態に比べれば進歩」
正:「動的スコープは、グローバルスコープしかない状態に比べれば進歩」
誤:「ローカルスコープは、関数ごとにあるスコープです。」
正:「ローカルスコープは、関数ごとにある対応表です。」
変更前:「2006年に採用された方法」
変更後:「2006年にPython 3.0で採用された方法」
補足説明:直前で2001年にPython2.1に入った修正の話をしていたので「誤植なのだろうか?」などと混乱させてしまいました。
誤:「非ゼロの整数」
正:「非負の整数」
修正前:「2つT型の値をとって、T型を返す関数」であることから推論しているわけです。
修正後:「2つT型の値をとって、T型を返す関数」であることから、言語処理系が「引数や返り値の型は整数だ」と推論しているわけです。
誤:この場合は、引数や返り値の型として人間「int」と書く必要があります。
正:この場合は、人間が「引数や返り値の型は整数(int)だ」と宣言する必要があります。
補足説明:後半に誤植がありました。また主語を補って対比が明確になるように修正しました。
誤:「10ではなく2で位取りをする」という方法(2進法)が発明しました。
正:「10ではなく2で位取りをする」という方法(2進法)が発明されました。
脚注の追加:「ここでは厳密な定義は避けて、おおまかなイメージを解説しています。厳密な定義の解説はほかの本に譲ります。たとえば「C言語による最新アルゴリズム事典」では「定数c(> 0),Nが存在して,n≧Nならば必ず|f(n)|≦c|g(n)|が成り立つとき,“n→∞のときf(n)=O(g(n))である”という」と解説されています。」
誤:「「オーダーエヌ」や「オーエヌ」」
正:「「オーダーエヌ」や「オーエヌ」、「線形時間」」
誤:「「オーダーイチ」や「オーワン」」
正:「「オーダーイチ」や「オーワン」、「定数時間」」
補足説明:p.141のO記法のコラムでは、O記法の厳密な定義に触れずに、大まかなイメージを解説をしました。しかし、肝心の「厳密な定義を避けてざっくり解説している」ということが読者に伝わらない可能性があるので脚注を追加しました。また、「定数時間」「線形時間」という表現方法に言及がないのももったいないので、脚注に加筆しました。
修正前:「ハッシュ」という言葉に馴染みのある方も多いだろうと思い、並べて書きましたが、ハッシュという言葉は辞書の実装方法の一つを指しているので、並べるのは適切ではありません。
修正後:スクリプト言語では、この種のコンテナを指して「ハッシュ」という言葉を使うことが多いです。これは辞書の実装方法の一つである「ハッシュテーブル」が由来なので、辞書と同列に並べることは厳密には正しくありません。ここではこの章の内容をわかりやすくするために、あえて書いています。
補足説明:「ハッシュ」という用語は、たとえばRubyのリファレンスマニュアルでも「ハッシュを作成する」などと言った書かれ方をしており、 読者によっては「連想配列」や「辞書」という用語よりも「ハッシュ」という用語を使った方が理解しやすいという人も多いかと思います。 しかし一方でこの使い方が問題だと考える人もいます。ここではそれを補足する意味で脚注8を書いたのですが、説明が悪くて伝わりにくいようですので修正します。
誤:「値を複数個入れる」という目的のために、配列と連結リストと複数の実現方法があったように、「文字列と値の対応を入れる」という目的のためにもいくつかの実装があります。
正:「値を複数個入れる」という目的のために、配列と連結リストの2つの実現方法があったように、「名前と値の対応を入れる」という目的のためにも、いくつかの実現方法があります。
誤:「たとえば10011というビット列は、アルファベットモードならのWを意味しますが、数字モードなら2を意味します。」
正:「たとえば10011というビット列は、アルファベットモードならWを意味しますが、数字モードなら2を意味します。」
修正前:まとめる手段はいろいろあります。言語によってどれを選択するかまちまちです。ここでは、まずC++やJavaが選択しなかった方法について解説していきます。
修正後:まとめる手段はいろいろあります。言語によってどれを選択するかまちまちです。クラスというC++やJavaが採用した方法が有名ですが、ここでは、まずクラス以外の方法について解説していきます。
補足説明:Perlの「パッケージを使う」という選択肢をJavaは *オブジェクトを作る方法としては* 採用しなかったのですが、パッケージ自体は複数のクラスをまとめる目的で採用しており、ここが混乱のもとになるため修正しました。
誤:「{"value" => 0}」ソースコード中に2箇所、本文中に2箇所、P196のソースコード中に1箇所
正:「{"count" => 0}」
誤:「"value"というキーに0という整数が対応付けられているハッシュ」
正:「"count"というキーに0という整数が対応付けられているハッシュ」
誤:「$valueに代入」
正:「$valuesに代入」
補足説明:「カウンターの値なんだからvalueという抽象的な変数名よりcountの方がいい」という意図で変更したのですが、変更し忘れがあったようです。
誤:「{"value" => 0}」
正:「{"count" => 0}」
誤:「{count => 0}」
正:「{"count" => 0}」
図中のCounterとCountが大文字始まりですが、これは図が誤りで、正しくはcounterとcountです。
説明の順番を改善しました: new演算子の挙動について
ストーリー仕立ての補足説明を作りました: リスコフの置換原則
誤「CLUという言語」
正「第6章の67ページで出てきた言語、CLU」
p.238
誤:「Barbara Liskov 216」正:「Barbara Liskov 67, 216」
追加:「Dijkstra, Edsger Wybe 37, 179」
p.240
誤:「Liskov 216」正:「Liskov, Barbara 67, 216」