注意: 「純粋な」機能とは、「純粋な仮想」
を意味するものではありません。
関数がグローバル状態を「読み取る」場合、それは自動的に不純になりますか? それとも他の要因に依存しますか?
自動的に不純になる場合は、その理由を説明してください。
他の要因に依存する場合は、それらが何であるかを説明してください。
注意: 「純粋な」機能とは、「純粋な仮想」
を意味するものではありません。
関数がグローバル状態を「読み取る」場合、それは自動的に不純になりますか? それとも他の要因に依存しますか?
自動的に不純になる場合は、その理由を説明してください。
他の要因に依存する場合は、それらが何であるかを説明してください。
「純粋な」関数は、結果が入力引数のみに依存する関数です。それ以外のものを読み取る場合、それは純粋な関数ではありません。
特定の特殊な例では、はい。たとえば、関数によってのみ読み書きされる計算済みの値のグローバル キャッシュがある場合、出力は入力のみに依存するという意味で数学的に純粋ですが、純粋ではありません。最も厳密な意味で。例えば:
static int cache[256] = {0};
int compute_something(uint8_t input)
{
if(cache[input] == 0)
cache[input] = (perform expensive computation on input that won't return 0);
return cache[input];
}
この場合、他の関数がグローバルに触れない限り、cache
技術的には外部のグローバル状態に依存していても、数学的に純粋な関数のままです。ただし、この状態はパフォーマンスの最適化にすぎません。この状態がなくても、同じ計算をより遅く実行します。
たとえば、Haskellでは、不純な側で乱数の無限のリストを作成し、そのリストを純粋関数に渡すことができます。実装は、純粋関数が必要な場合にのみ使用する次の数値を生成しますが、関数は依然として純粋です。
純粋な式を作成するには、純粋な関数が必要です。定数式は定義上純粋です。
したがって、グローバルな「状態」が変わらなければ問題ありません。
参照透過性も参照してください。
より微妙な例は、グローバル変数 (または動的スコープ変数、またはレキシカル クロージャー) を使用して結果の計算を支援する関数の例です。この変数はパラメーターとして渡されませんが、変更できるため、パラメーターが同じであっても、関数への後続の呼び出しの結果が異なる場合があります。(純粋な関数型プログラミングでは、破壊的な代入は許可されていません。したがって、これらの変数は変更できないため、グローバル (または動的スコープ) 変数を使用する関数は依然として参照透過的です。)