利点は、純粋な関数によりコードの推論が容易になることです。または、言い換えると、副作用によりコードの複雑さが増します。
computeProductPrice
メソッドの例を見てみましょう。
純粋なメソッドは、製品の数量、通貨などを要求します。メソッドが同じ引数で呼び出されると、常に同じ結果が生成されることを知っています。
- それをキャッシュして、キャッシュされたバージョンを使用することもできます。
- 値を変更せずに、実際に必要なときに遅延させて呼び出しを延期することができます。
- 副作用がないことを知って、メソッドを複数回呼び出すことができます。
- 必要なのは引数だけであることを知っているため、メソッド自体を世界から隔離して推論することができます。
非純粋なメソッドは、使用とデバッグがより複雑になります。引数以外の変数の状態に依存し、それらを変更する可能性があるため、複数回呼び出されたときに異なる結果を生成したり、まったく呼び出されなかったり、あまりにも早くまたは遅すぎて呼び出されたときに同じ動作をしないことがあります。
例
フレームワークに数値を解析するメソッドがあると想像してください:
decimal math.parse(string t)
以下に依存するため、参照の透明性はありません。
ナンバリングシステムを指定する環境変数、つまり、Base 10または他の何か。
math
解析する数値の精度を指定するライブラリ内の変数。そのため、の値で1
は、文字列"12.3456"
を解析するとが得られ12.3
ます。
カルチャ。予想されるフォーマットを定義します。例えば、とfr-FR
、解析が"12.345"
与える12345
、区切り文字がする必要があるため,
ではなく、.
そのような方法で作業することがどれほど簡単か難しいか想像してみてください。同じ入力で、メソッドを呼び出す瞬間に応じて根本的に異なる結果を得ることができます。何かが環境変数を変更したり、カルチャを切り替えたり、異なる精度を設定したりするためです。メソッドの非決定的な特性は、より多くのバグとより多くのデバッグの悪夢につながります。いくつかの並列コードが8進数を解析していたので、呼び出して答えとしてmath.parse("12345")
取得5349
するのは良くありません。
この明らかに壊れた方法を修正するには?参照の透明性を導入する。言い換えると、グローバル状態を取り除き、すべてをメソッドのパラメーターに移動することにより:
decimal math.parse(string t, base=10, precision=20, culture=cultures.en_us)
メソッドが純粋になったので、メソッドをいつ呼び出しても、同じ引数に対して常に同じ結果が生成されることがわかります。