多くのテキスト、特に関数型プログラミングのテキストを見て、特定のCSの概念"do n't compose"を主張しています。たとえば、ロックは構成せず、モナドは構成しません。
私はこのフレーズの意味を正確に追跡するのに苦労してきました。構成について考えるとき、私は関数構成またはオブジェクト集約のいずれかを考えます(「継承よりも構成を優先する」のように)が、ここでは人々がそれを使用しているという意味ではないようです。
上記の2つの例のような式(つまり、ロックとモナド)でこのフレーズが使用されている場合、誰かがこのフレーズの意味を説明できますか?
人々が「Xは構成しない」と言うとき、彼らが「構成」によって意味するものは、実際には単に「まとめる」ことを意味し、そしてwhatとhowを組み合わせて「X」が正確に何であるかによって、非常に異なります。
また、「作成しない」と言う場合、若干異なることを意味する場合があります。
#1の例は、スキャナー/レクサーを備えたパーサーです。 「スキャナー/レクサーは構成しない」というフレーズを聞くかもしれません。それは実際には真実ではありません。それらが意味することは、「別の字句解析ステージを使用するパーサーは構成しない」です。
なぜパーサーを作成したいのですか?さて、あなたがIDEベンダーであり、Webフレームワーク用にIDE=を構築したいと考えているとします。通常のWeb開発では、言語を混合することがよくあります。ECMAScriptを含む<script>
要素とCSSを含む<style>
要素を含むHTMLファイルがあります。HTML、いくつかのプログラミング言語、およびいくつかのテンプレート言語メタ構文を含むテンプレートファイルがあります。 「Python」、「テンプレートに埋め込まれたPython」、「CSS」、「HTML内のCSS」、「ECMASCript」、「HTML内のECMAScript」、「HTML」、「HTML内」に異なる構文強調表示を記述したくないテンプレート」などのように記述します。Python用、HTML用、テンプレート言語用のシンタックスハイライターを作成し、3つをテンプレートファイルのシンタックスハイライターに構成します。
ただし、レクサーはファイル全体をトークンのストリームに解析しますが、これはその1つの言語に対してのみ意味があります。他の言語のパーサーは、レクサーが渡したトークンを処理できません。たとえば、Pythonパーサーは通常、字句解析器がインデントを追跡し、偽のINDENT
およびDEDENT
トークンをトークンストリームに挿入するように記述されています。したがって、Pythonの構文が実際にはそうではない場合でも、パーサーをコンテキストフリーにすることができますが、HTMLレクサーは空白を完全に無視します。
ただし、単純に文字を読み取るスキャナーレスパーサーは、文字ストリームを別のパーサーに渡すことができます。別のパーサーは、それを引き渡すことができるため、構成がはるかに簡単になります。
#2の例は、SQLクエリを含む文字列です。 2つの文字列を使用でき、それぞれに構文的に正しいSQLクエリがありますが、2つの文字列を連結すると、結果が構文的に正しいSQLクエリにならない場合があります。そのため、ARel
のようなクエリ代数があり、doで構成されています。
ロックは#3の例です。ロック付きの2つのプログラムがあり、それらを組み合わせて1つのプログラムにした場合でも、ロック付きのプログラムはありますが、元の2つのプログラムが完全に正しく、デッドロックと競合がない場合でも、結果のプログラムには必ずしもこれはありません。プロパティ。ロックの正しい使用法は、プログラム全体のグローバルプロパティであり、プログラムの作成時に保持されないプロパティです。これは、たとえばdoが構成するトランザクションとは異なります。トランザクションを正しく使用するプログラムは、別のそのようなプログラムと組み合わせることができ、トランザクションを正しく使用する結合プログラムを生成します。
構成可能性とは、プログラムコンポーネントを簡単かつ確実に組み合わせて、より大きなコンポーネントとより複雑な機能を生成できることを意味します。
コンポーネントをより構成しやすくするいくつかのこと:
Idempotence。べき等関数は、同じパラメーター値で複数回呼び出された場合、常に同じ出力または副作用を生成します。関数呼び出しの結果は予測可能であるため、これにより構成可能性が向上します。
Referential Transparency。参照透過式は常に同じ結果に評価されます。これにより、ロックを使用せずに、同一の式を相互に置き換えたり、式を互いに独立して(つまり、異なるスレッドで)計算したりすることで、構成可能性が向上します。
不変性。不変オブジェクトの状態は、いったん作成されると変更できません。これにより、作成後にオブジェクトの状態が変更された関数やオブジェクトがあるかどうか心配することなく、オブジェクトの安定した値に依存できるため、構成可能性が向上します。
Purity。純粋な関数には副作用がありません。それらには入力と出力しかありません。これにより、ある関数の出力を別の関数の入力に入れることができるので、関数の外側の何かが変更されたかどうかを心配する必要がありません。
ロックは、何らかの状態を共有する2つの操作を組み合わせるときに依存する必要のある外部要素であり、ロックの使用に固有の複雑さに関係するあらゆる種類の理由のため、構成しません。
「モナドは構成しない」というフレーズは、私にはあまり意味がありません。モナドの要点は、キーボード入力や画面出力などのステートフルなものを取り、それをより純粋で数学的な形式に変換することです。