We've seen the power of computational objects with local state as
tools for modeling. Yet, as
section
[3.1.3]
warned, this power extracts a price: the loss of referential
transparency, giving rise to a thicket of questions about sameness and
change, and the need to abandon the substitution model of evaluation in
favor of the more intricate environment model.
ローカル状態を持つ計算オブジェクトがモデリングの道具としていかに強力であるかを見てきました。しかし、セクション
[3.1.3]で警告したように、この力には代償があります。参照透過性が失われ、同一性と変化にまつわる込み入った問題が次々と生じ、評価の置換モデルを捨ててより複雑な環境モデルへと移らざるを得なくなるのです。
The central issue lurking beneath the complexity of state, sameness,
and change is that by introducing assignment we are forced to admit
time into our computational models. Before we introduced
assignment, all our programs were timeless, in the sense that any
expression that has a value always has the same value. In contrast,
recall the example of modeling withdrawals from a bank account
and returning the resulting balance,
introduced at the beginning of
section
[3.1.1]:
状態、同一性、変化をめぐる複雑さの根底に潜む中心的な問題は、代入を導入することによって計算モデルに
時間という概念を認めざるを得なくなる、ということです。代入を導入する前は、私たちのプログラムはすべて時間に関わりがないものでした。式の値はつねに同じである、という意味においてです。これに対して、セクション
[3.1.1]の冒頭で紹介した、銀行口座からの引き出しをモデル化して残高を返す例を思い出してください:
Here successive evaluations of the same expression yield different
values. This behavior arises from the fact that the execution of
assignments (in this case, assignments to the variable
balance) delineates moments in time
when values change. The result of evaluating an expression depends not
only on the expression itself, but also on whether the evaluation occurs
before or after these moments. Building models in terms of computational
objects with local state forces us to confront time as an essential concept
in programming.
ここでは、同じ式を繰り返し評価すると、毎回異なる値が返ってきます。この振る舞いは、代入(この場合は変数balanceへの代入)の実行が、値が変化する時点を区切る、という事実から生じます。式を評価した結果は、式そのものだけでなく、評価がそれらの時点の前に行われるのか後に行われるのかにも依存します。ローカル状態を持つ計算オブジェクトを用いてモデルを組み立てるということは、時間をプログラミングの本質的な概念として受け入れざるを得なくします。
We can go further in structuring computational models to match our
perception of the physical world. Objects in the world do not change
one at a time in sequence. Rather we perceive them as acting
concurrently—all at once. So it is often natural to
model systems as collections of
threads (sequences of computational steps)
that execute concurrently.
物理世界に対する私たちの認識に合うように、計算モデルの構造をさらに進めることもできます。世界の中の物体は、一度に一つずつ順番に変化するわけではありません。むしろ私たちは、物体が並行に—つまり同時に—動いていると捉えています。そこでシステムを、並行に実行される
スレッド(計算ステップの列)
の集まりとしてモデル化するのが自然であることが多いのです。
Just as we can make our programs modular by
organizing models in terms of objects with separate local state, it is
often appropriate to divide computational models into parts that evolve
separately and concurrently. Even if the programs are to be executed on
a sequential computer, the practice of writing programs as if they were
to be executed concurrently forces the programmer to avoid inessential
timing constraints and thus makes programs more modular.
それぞれ独立したローカル状態を持つオブジェクトの観点からモデルを構成することでプログラムをモジュール的にできるのと同じように、計算モデルをそれぞれ別個に並行に発展していく部分に分割することも、しばしば適切です。たとえプログラムが逐次型コンピュータ上で実行される場合であっても、あたかも並行に実行されるかのようにプログラムを書くという習慣は、プログラマに本質的でないタイミング上の制約を避けることを強い、結果としてプログラムをよりモジュール的にしてくれます。
In addition to making programs more modular, concurrent computation
can provide a speed advantage over sequential computation. Sequential
computers execute only one operation at a time, so the amount of time
it takes to perform a task is proportional to the total number of
operations performed.
プログラムをよりモジュール的にするだけでなく、並行計算は逐次計算に対して速度面での利点ももたらしえます。逐次型コンピュータは一度に一つの演算しか実行しないため、タスクを実行するのにかかる時間は、実行される演算の総数に比例します。
However, if it is possible to decompose a problem into pieces that are
relatively independent and need to communicate only rarely, it may be
possible to allocate pieces to separate computing processors,
producing a speed advantage proportional to the number of processors
available.
しかし、もし問題を比較的独立していて互いにほとんど通信を必要としない部分へと分解できるなら、それらの部分を別々の計算プロセッサに割り当てることができ、利用可能なプロセッサの数に比例した速度向上が得られる可能性があります。
Unfortunately, the complexities introduced by assignment become even
more problematic in the presence of concurrency. The fact of
concurrent execution, either because the world operates in parallel or
because our computers do, entails additional complexity in our
understanding of time.
残念ながら、代入によってもたらされる複雑さは、並行性が関わってくるとさらに厄介なものになります。世界が並列に動いているためにせよ、私たちのコンピュータが並列に動いているためにせよ、並行実行という事実は、時間についての私たちの理解にさらなる複雑さを強います。