あらすじ
本書は,プログラミング言語が持つ各種概念が「なぜ」存在するのかを解説する書籍です。
世の中にはたくさんのプログラミング言語があります。そしてプログラミングに関する概念も,関数,型,スコープ,クラス,継承など,さまざまなものがあります。多くの言語で共通して使われる概念もあれば,一部の言語でしか使われない概念もあります。これらの概念は,なぜ生まれたのでしょうか。本書のテーマは,その「なぜ」を理解することです。
そのために本書では,言語設計者の視点に立ち,複数の言語を比較し,そして言語がどう変化してきたのかを解説します。いろいろな概念が「なぜ」生まれたのかを理解することで,なぜ使うべきか,いつ使うべきか,どう使うべきかを判断できるようになるでしょう。そして,今後生まれてくる新しい概念も,よりいっそう理解しやすくなることでしょう。
感情タグBEST3
このページにはネタバレを含むレビューが表示されています
Posted by ブクログ
黄色のハイライト | 位置: 761
構文解析器(パーサ)は、ソースコードを文字列として読み込んで、それを解析し、構文木を作るプログラムです。FORTRANでプログラムがコンパイルされる際にも、この構文解析器がソースコードの文字列を構文木に変換する作業を行っている
黄色のハイライト | 位置: 773
情報は膨大です。「とにかく全部一通り勉強しよう」という戦略はもはや通用しません。必然的に「何を学ぶか、何を学ばないか」を決める必要が出てきます。そのときの指標になるのが「何を作りたいのか」目的を明確にすることです。そして目的を達成するために必要なことから学べばよいのか。
黄色のハイライト | 位置: 776
何を作るかを決めることができない? もしかして、最初から完璧なものを作ろうと考えていませんか? 誰も考えたことのないもの、みんなが絶賛してくれるものを作ろうと考えていませんか? 最初からすごいものを作ろうと考えて、そのせいで手が動かなくなっているのだとすると、いつまで経ってもすごいものは作れないでしょうね。まずは簡単なものでよいので何かを作りましょう。
黄色のハイライト | 位置: 888
今では「コンパイルしてアセンブリ言語に変換し、アセンブルして機械語に変換し、リンクしてつなぎあわせて1つの実行可能ファイルにする」という一連の作業をまとめてコンパイルと呼ぶことも多いかと思いますが、ここではアセンブリ言語に変換することを指してコンパイルと呼んでいる。
黄色のハイライト | 位置: 1,392
1975年にJohn Goodenoughは自らの論文( 注9)の中で、より良い例外処理の方法を提案しました( 注10)。彼の主張はこうです。“プログラマは「命令が例外を投げる可能性があることを忘れる」「適切でない場所、または適切でない種類の例外処理を書く」などの失敗をする可能性がある。この可能性を減らし、プログラマがした失敗をコンパイラが警告できるようにするには、2つのものが必要だ。一つは命令がどういう例外を投げる可能性があるかを明示的に宣言させること。そしてもう一つは字句的に「失敗しそうな処理」を囲む構文。
黄色のハイライト | 位置: 1,573
こういう「おかしくなったら処理を停止して速やかに報告すべき」という設計思想は「フェイルファースト」と呼ばれています。ソフトウェアの目的によっては簡単に停止してもらっては困る場合もあるでしょうが、少なくとも学習や開発の段階では、間違えたときにすぐに間違えたことに気付けることのメリットは大きいです。
黄色のハイライト | 位置: 1,666
本章では、プログラムも失敗することがあること、そしてその失敗をどうやって伝えるかを学びました。失敗を伝える方法は大きく分けて2通りあります。「返り値で伝える」と「失敗したらジャンプする」。
黄色のハイライト | 位置: 2,217
銀行や為替などのお金を扱う分野ではこの振る舞いが嫌われるので、そういう場合には固定小数点数やエクセス-3のような10進法での計算が使われます。
黄色のハイライト | 位置: 3,252
一つは「切りの良いところで交代」です。処理の区切りが良いところで処理が自発的に「交代していいよ」とする方法です。この方法で実現されているマルチタスク(並行処理)を協調的マルチタスクと言い
黄色のハイライト | 位置: 3,254
この方法では、どれか1つの処理が「交代していいよ」と言わずに実行を続けると、ほかの処理にいつまで経ってもチャンスが回ってこないという問題点があります。あくまで「すべての処理が、適度な間隔で『交代していいよ』と言う」という信頼のもとで成り立っているシステム
黄色のハイライト | 位置: 3,261
「どういうときに交代するか」のもう一つの決め方は「一定時間で交代」です。この方法では、個々のプログラムよりも偉い立場のプログラム(タスクスケジューラ)が存在します。それが一定時間ごとに今走っている処理を強制的に中断させ、ほかのプログラムが処理を実行できるようにします。 ゲームのたとえで言うならば、母が15分おきに「交代しなさい!」と命令するような状況です。コンピュータの場合は人間が見ても中断されたとわからないように、たとえば20ミリ秒(0.02秒)で交代しています。 この方法で実現されているマルチタスクをプリエンプティブマルチタスクと言います。プリエンプティブとは「他人の行動を阻止するための」という意味の単語で、この手法は協調的マルチタスクと違って「止められる側のプログラムの協力」がなくても強制的に処理を止めてしまうところが特徴です( 注
黄色のハイライト | 位置: 3,270
Windows 95、Mac OS X以降や、UNIX、LinuxなどはみんなOS自体がこの方法で複数のプログラムを並行実行してい
黄色のハイライト | 位置: 3,289
この良くない現象のことを「競合状態」(レースコンディション)と呼んだり、このプログラムを「スレッドセーフでない」と表現したりし
黄色のハイライト | 位置: 3,334
Bさんは「Aさんの書類トレー」に書類を入れてすぐに自分の仕事に戻ります。これがアクターモデルです。 処理は非同期に行われます。Aさんが書類トレーの中の書類をいつ処理するかはBさんにはわかりません。いつ処理が終わったのかも、書類に「終わったらBまで送り返してください」とでも書いておいて、いずれBさんが自分の書類トレーの中でAさんからの返事を発見したときにようやく「ああ、終わったんだな」とわかるしくみです。 この特徴が向いている処理として、まさにメッセージのやりとりそのものが挙げられます。TwitterやFacebookなどの「大量のユーザの間でのメッセージのやりとりを扱うサービス」では、おそらくアクターモデルが向いている処理が多いのでしょ
黄色のハイライト | 位置: 3,356
一つは、ファイバーやコルーチン、グリーンスレッドなどと呼ばれている手法です。スレッドがプリエンプティブなことが割り込まれてしまう原因なのだから、協調的なスレッドを作ればいいじゃないか、というアプローチです。RubyのFiberクラスや、PythonやJavaScriptのジェネレータがこれです( 注
黄色のハイライト | 位置: 3,369
この方法にはいろいろなバリエーションがあり、ロック、ミューテックス、セマフォなどいろいろな名前がありますが、コアのコンセプトは「使用中」の札と同じです( 注11)。「ロック」という名前のせいで「ロックを掛けておけばほかの人は入ってこられない」という勘違いをしがちですが、しかし実際は「使用中」の印を付けるだけ、印を確認しないで実行するスレッドがいると台無しになってしまいます。処理の流れの一部分だけ協調的に譲り合うしくみと言えるでしょ
黄色のハイライト | 位置: 3,411
共有されたXとYを書き換える処理AとBがあるとしましょう。Aが「Xをロックして、Yをロックする」という順でロックをかけていて、Bが「Yをロックして、Xをロックする」という順でロックをかけている場合、タイミングによっては問題が発生します。AがXをロックし、BがYをロックした状態で、お互いに相手がロックを解放するのを待ってしまうのです。 これがデッドロックと呼ばれる現象です。この問題を回避するためにプログラマは、プログラム全体でロックの順番が一貫するように気を付けなければいけません。「何をロックすべきか」だけではなく「どういう順でロックすべきか」も把握しなければいけないの
黄色のハイライト | 位置: 3,431
この問題を解決しようとしているのがトランザクショナルメモリというアプローチです( 注13)。データベースのトランザクションの考え方をメモリにも使う方法です。コンセプトは「手元で試しにやってみて、失敗だったら最初からやりなおし、成功だったら変更を共有する」です( 図10.2)。XやYを直接書き換えるのではなく、一時的に別のバージョンを作ってそれを書き換え、ひとかたまりの処理が終わってから反映するのがポイント
黄色のハイライト | 位置: 3,492
本章では、並行処理についての重要な概念を学びました。並行処理は昔から大勢の人を悩ませてきた問題で、いまだに多くの人を悩ませ続けている問題です。歴史を追うと、共有→非共有→共有、協調→非協調→協調、ハードウェア→ソフトウェア→ハードウェア、と振り子のように2つの解の間を揺れているように感じます。片方だけでなく両方を学び、バランス良く使うことが大事なのかもしれません
黄色のハイライト | 位置: 3,982
今では子クラスを作るときに気を付けるべきポイントとしてよく言及されるのが「リスコフの置換原則」です。 その原則はこうです──「T型のオブジェクトxに関してある属性q(x)が常に真であるとする。SがTの派生型であれば、S型のオブジェクトyの属性q(y)が常に真でなければならない。」( 注4)。 今の文脈で言い換えると、「あるクラスTのオブジェクトについて必ず成り立つ条件があるなら、その条件はTの子クラスSのオブジェクトについても必ず成り立たなければいけない」となるでしょう( 注5)。
黄色のハイライト | 位置: 4,193
そもそも、なぜ多重継承はこんなに問題になっているのでしょう? 2002年に発表された、トレイトに関する論文( 注17)では問題点がとてもよく整理されています。 クラスには2つの相反する役割があります。1つ目は「インスタンスを作るためのもの」という役割で、このためには「完結した、必要なものを全部持った、大きなクラス」である必要があります。2つ目は「再利用の単位」という役割で、このためには「機能ごとの、余計な物を持っていない、小さなクラス」である必要があります。 クラスが「インスタンスを作るためのもの」として使われているときには、再利用の単位としては大きすぎるのです。それならば、再利用の単位という役割に特化した、もっと小さい構造(トレイト=メソッドの束)を作ればよいのではないか?──これがトレイトの考え方です。再利用の単位をクラスと別に作るという点では、Rubyのモジュールに似ていますね。何が違うのでしょ