繰り返し呼び出されたときに、一度呼び出すのと同じ効果を持つ関数の用語は何ですか?


96

(シングルスレッド環境を想定)

この基準を満たす関数は次のとおりです。

bool MyClass::is_initialized = false;

void MyClass::lazy_initialize()
{
    if (!is_initialized)
    {
        initialize(); //Should not be called multiple times
        is_initialized = true;
    }
}

本質的に、この関数を複数回呼び出すことができ、MyClass複数回初期化することを心配する必要はありません

この基準を満たさない関数は次のとおりです。

Foo* MyClass::ptr = NULL;

void initialize()
{
    ptr = new Foo();
}

initialize()複数回呼び出すと、メモリリークが発生します。

動機

この基準を満たすことが期待される関数に適切にコメントできるように、この動作を説明する簡潔な単語を1つ用意しておくとよいでしょう(特に、オーバーライドされると予想されるインターフェース関数を記述する場合に便利です)


67
近い投票者へ:すべての「名前を付ける」質問の99.999%(概算)がトピックから外れているのは事実ですが、それらは単一の、正確で、明確な、客観的な回答を持たず、命名は、この1つは、純粋に主観的意見に基づいている OP自身によって与えられた、単一の、正しい、明確な、客観的な答えを持っています。
イェルクWミッターク

30
複数回それを呼び出すと、ない間に「VAR」を変更し、他のコードがあるかもしれないとして、効果を持っています。
RemcoGerlich

7
OP が尋ねたときに答え知っていたのに、なぜこの質問が尋ねられたのですか?担当者/ポイント/カルマの構築以外の理由はありますか?
dotancohen

13
@dotancohen Q / Aスタイルの自己応答は、StackExchangeの重要な概念の1つです。
glglgl

17
@glglgl:メリットのある質問には同意します。この質問にはどんなメリットがありますか?私は、CS 101のすべての質問をOPが尋ね、すぐに回答し、CSの各用語がOPが質問し、すぐに定義し、基本アルゴリズムの長所と短所を質問し、OPがすぐに回答することを真剣に懸念しています(必ずしもこのOPではありません)。それは、私たちがsoftwareengineering.SEに望むサイトですか?
dotancohen

回答:


244

このタイプの関数/操作は、べき等と呼ばれます

dem等性(英国:/ ˌɪdɛmˈpoʊtəns /、[1]米国:/ˌaɪdəm-/)[2]は、数学およびコンピューターサイエンスの特定の操作の特性であり、最初の適用を超えて結果を変更せずに複数回適用できます。

数学では、これは場合を意味fは冪等であるFF(X))= fは(x)は、と言っと同じであるFF = Fを

コンピューターサイエンスでは、これがべきf(x);等である場合f(x);、と同じであることを意味しf(x); f(x);ます。

注:これらの意味は異なるように見えますが、状態表示的意味論では、「べき等」という言葉は実際には数学とコンピューターサイエンスの両方でまったく同じ意味を持っています。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
maple_shaft

51

これの正確な用語は(ウーファスが言及しているようにべき等です。私はあなたを呼び出すことができながら、ことを追加したいfunc1メソッドの冪等を、あなたはそれを呼び出すことができませんでした純粋な機能。純粋関数のプロパティは2つあります。それはi等である必要があり、副作用、つまりローカル静的変数、非ローカル変数、可変参照引数またはI / Oストリームの変更がないことです。

私がこれに言及する理由は、技術的にi等性は副作用ではなく関数の戻り出力を参照するため、副作用を持つwith等関数も良くないからです。したがって、技術的にfunc2は、出力は入力に応じて変化しないため、メソッドはべき等です。

ほとんどの場合、純粋な関数が必要であることを指定する必要があります。純関数の例は次のとおりです。

int func1(int var)
{
    return var + 1;
}

詳細については、ウィキペディアの記事「純粋な機能」を参照してください


37
あなたのi等性の定義は狭すぎる、または別の言い方をすると、プログラミングではなく、mathematical等性の数学的な定義を使用していると思います。たとえば、PUTおよびDELETEHTTPメソッドは、それらの副作用を複数回実行すると1回だけ実行するのと同じ効果があるため、正確にべき等と呼ばれます。プログラミングでは、「実行は実行と同じ効果がある」ことを意味するのに対して、「べき等性」とはあなたが言っていることです。「world」パラメータを追加することにより、2番目の意味を簡単に前者に変換できることに注意してください。f∘f = fff; f
イェルクWミッターク

23
@Neil「I等性は厳密には数学用語です。」いいえ、そうではありません。ネットワークやクライアントサーバー通信/分散システムでも使用されており、JörgWMittagで説明されているとおりです。元のメッセージの動作を変更せずに、同じ操作/メッセージでサーバー/クライアントへの複数の要求を許可するため、便利な概念です。これは、信頼性の低い通信があり、クライアントメッセージが削除されたか、サーバーの応答が削除されたためにコマンドを再試行する必要がある場合に便利です。
opa

7
純粋とべき等の違いについてさらに詳しく説明する必要があります。あなたの例のfunc1は、dem等ではありませんfunc1(1) != func1(func1(1))
20:29のテズラ

5
純度とべき等は異なります。純粋な関数は、数学的な意味でi等である必要はありません(副作用がないという点で、明らかにdem等です)。OPの例のように、I等(プログラミングの意味で)関数は純粋である必要はありません。また、opaで述べたように、べき等性は純度とは厳密に異なる用途を持つ有用なプロパティです。「ide等的で副作用のない」としての純度の定義は間違っているか、少なくとも誤解を招くようなダウン投票です。
Frax

5
プログラミングのコンテキストでは「副作用」はありませんが、定義を拡張してこれを含めると、べき等関数と純粋関数は同じ意味になります。いいえ、同じことを意味するものではありません。dem等、純粋ではない:void f(int var) { someGlobalVariable = var; }。冪等、純粋ではありません:int func1(int var) { return var + 1; }
JLRishe

6

用語はI等です。以下で、べき等関数(それ自体で再帰的に呼び出される; 2番目のコードブロックと数学的定義)と機能的i等性(同じ入力で繰り返し呼び出される;最初のコードブロックとプログラミングでしばしば使用される用語)には明確な違いがあることに注意してください。

副作用のある関数fは、逐次合成fのもとでi等であると言われます。f、同じ引数のリストで2回呼び出されたときに2番目の呼び出しに副作用がなく、最初の呼び出しと同じ値を返す場合[引用が必要](最初の呼び出しの終わりから開始までの間に他の手続きが呼び出されなかったと仮定する2番目の呼び出しの)。

たとえば、次のPythonコードを検討してください。

x = 0

def setx(n):
    global x
    x = n

setx(5)
setx(5)

ここで、setxの2番目の呼び出し(同じ引数)は可視のプログラム状態を変更しないため、setxはべき等です。xは最初の呼び出しですでに5に設定され、2番目の呼び出しで再び5に設定されます。同じ値。これは、関数合成f∘fにおけるi等性とは異なることに注意してください。たとえば、絶対値は関数合成の下ではべき等です。

def abs(n):
    if n < 0:
        return -n
    else:
        return n

abs(-5) == abs(abs(-5)) == abs(5) == 5

3

物理学では、これが投影と呼ばれることを聞いたことがあります。

突起は線形変換であり、P自体のベクトル空間からようにP 2 = P。つまり、Pが任意の値に2回適用されるたびに、1回適用された場合と同じ結果が得られます(べき等)。

グラフィカルに、これはベクトル投影の漫画を見ると理にかなっています:

ここに画像の説明を入力してください

画像において、1の投影であるまでに、Bあなたの関数の最初のアプリケーションのようです。a 1からbへの後続の投影で、同じ結果a 1が得られます。つまり、プロジェクションを繰り返し呼び出すと、1回呼び出すのと同じ効果があります。

公正な警告:これが物理学以外で使用されることは聞いたことがないので、チームにこれらのタイプがない場合は、全員を混乱させる可能性があります。


2
これは実に、べき等関数をどのように視覚化できるかの素晴らしい具体例です(数学的に、特にベクトル幾何学/線形代数分野で)。ソフトウェア機能の「べき等」は非常に近い概念ですが、開発者/コンピュータ科学者はこの文脈で「投影」という言葉を頻繁に使用するとは思いません(ソフトウェア工学の「投影関数」はむしろオブジェクトをとる関数を指しますそして、それから派生した新しいオブジェクト、またはそのオブジェクトのプロパティなどを返します)
Pac0

2
@ Pac0ああ、わかった。私は科学とプログラミングの境界に取り組んでいますが、その言葉がすでに過負荷になっていることに気付きませんでした。私はこの用語を使用する職場でのいくつかの不自然な例を考えることができますが、私は明らかに日常的に科学の専門用語に我慢する人々と協力します:-)
user1717828

3

同じ入力(この場合は入力なし)が与えられると、決定論的アルゴリズムであり、常に同じ出力を生成します。

コンピュータサイエンスでは、決定論的アルゴリズムは、特定の入力が与えられると、常に同じ出力を生成し、基になるマシンは常に同じ状態シーケンスを通過するアルゴリズムです。確定的アルゴリズムは、実際のマシンで効率的に実行できるため、これまでで最も研究されていて使い慣れたアルゴリズムであり、最も実用的なアルゴリズムの1つです。

SQLデータベースは、確定的関数に関心があります

決定論的な関数は、入力が同じ場合、常に同じ答えを返します。SQLiteのほとんどの組み込みSQL関数は決定的です。たとえば、abs(X)関数は、入力Xが同じである限り、常に同じ答えを返します。

関数は、インデックスの計算に使用される場合、確定的でなければなりません。

例えば、SQLiteの中で、以下の非決定的関数は、インデックスで使用することはできません:random()changes()last_insert_rowid()sqlite3_version()


6
質問者func2は決定論的です(ランダムな影響はありません)が、探しているプロパティに違反していると既に宣言されています。
Draco18s

同じ結果が繰り返しによって生成されることは、同じ結果がネストまたは連鎖によって生成されるということと同じではありません。決定論的な関数は、インデックス作成/ハッシュよりも結果のキャッシュに重要です。
mckenzm

3

この性質を有するfunctonに特定の入力がある場合、他の回答に加えて、それは固定点不変点又は不動点機能。たとえば、1の任意の累乗は1に等しいため、(1ⁿ)ⁿ=1ⁿ= 1です。

出力として自分自身を生成するプログラムの特殊なケースは、クインです。


カントールのセットは数学に関係しているので、クインはソフトウェアに関係します:-)。そしてもちろん、クインはi等ではありません。出力が既に存在する場合に失敗するか、前の結果を「上書き」して、同一の出力であるにもかかわらず新しいものを書き込みます。
カールヴィットフト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.