23

私の考えでは、関数の純粋さの力は、深いコード パスが副作用のないものとして検証できるときです。純粋な指定子の内部にあるコード ツリーの規模と、コードの再利用のレベルについて、人々の経験はどのようなものですか?

私が見つけたいくつかのこと:

std.algorithmはほとんど としてマークされていませんpureが、インスタンス化関数または mixin の純度を要求するアルゴリズムの純粋なバージョンによって、または純粋な指定子自体が静的にポリモーフィックであることによって、大部分が純粋である可能性があります。
のような便利なコンバーターto!string( someInt )は現在純粋ではありません。

ユーザー定義の構造体 には、次のような問題があるようです (以下に示すように)

次のコードは現在、DMD 2.052 win 32 ビットで複数のエラーを発生させます。

struct InnerStruct
{
    pure this(this) {}
    pure ~this() {}
}

struct OuterStruct
{
    InnerStruct innerStruct;
    pure this(this) {}
    pure ~this() {}
}

pure void somePureFunc()
{
    OuterStruct s1 = OuterStruct(); // pure nested destructor does not compile
    OuterStruct s2 = s1;
    InnerStruct is1 = InnerStruct(); // pure non-nested destructor seems to compile
    InnerStruct is2 = is1; // pure non-nested postblit does not compile
}

void main()
{
    somePureFunc();
}
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(20): Error: pure function 'somePureFunc' cannot call impure function '__cpctor'  
pure_postblit.d(18): Error: pure function 'somePureFunc' cannot call impure function '~this'  
pure_postblit.d(17): Error: pure function 'somePureFunc' cannot call impure function '~this'  
4

1 に答える 1

22

理論的にはpure、Dのポイントは、関数がどのように実装されているかに関係なく、関数に副作用がないことを保証できるようになっているということです。Dには2種類の純度があります。

  • マークされたすべての関数pureは弱く純粋です。グローバルな可変状態(グローバル変数、スレッドローカル変数、static変数など)にアクセスしたり、I/Oを実行したりすることはできません。しかし、彼らは彼らの議論を変えるかもしれません。これらの関数のポイントは、強い純粋の保証に違反することなく、強い純粋関数(以下に詳述)から呼び出すことができるということです。

  • 弱く純粋で、可変間接参照を持つ引数を持たないすべての関数は、非常に純粋です。const型構築子と型構築子を使用して、これimmutableを保証できます。(構造体とクラスを扱う場合、thisポインターはパラメーターと見なされます。)非常に純粋な関数には、可変状態を使用して実装されている場合でも、関数型プログラミングの人々が話す優れた特性がすべて備わっています。非常に純粋な関数は、指定された引数に対して常に同じ値を返し、観察可能な副作用はありません。非常に純粋な関数は参照透過性があります。つまり、観測可能な動作に影響を与えることなく、指定されたパラメーターのセットを使用して、関数の呼び出しの代わりに戻り値を使用できます。強く純粋な関数は、他の強く純粋な関数と並行して安全に実行できます。

残念ながら、ジェネリックコードとpureconstおよびimmutable)の間の相互作用はかなり貧弱です。これを修正するためのいくつかの提案がありましたが、まだ受け入れられていません。
\ std.algorithmは可能な限り汎用的に記述されているため、ラムダ関数と受け入れる範囲が純粋である必要はありません。さらに、D2で追加された型システム機能は、関連する問題を修正する前に、より基本的なものが優先されているため、一般に言語で最もバグの多い機能です。現在、purestd.mathのような些細な場合を除いて、基本的には使用できません。

于 2011-04-28T03:05:32.677 に答える