web-dev-qa-db-ja.com

副作用がある関数の命名規則?

彼らの言語には、状態を変化させる関数の名前が感嘆符で終わらなければならない慣習があると誰かが言うのを聞いた私はもっ​​と機能的なコードを書こうとしているのですが、副作用の状態に従って関数を何とかマークするアイデアが好きです。つまり、なし、内向きの副作用、外向きの副作用です(適切なfp用語を知らないのですが、望む)。

もちろん、自分の命名規則を思い付くのは簡単ですが、私が行ってホームベークする前に、そのようなスキームや慣習がすでに存在しているかどうか疑問に思っていました。

編集:すべての回答に感謝します。それはまさに私が求めていたものであり、それらはすべて本当に有用であるとわかりました。おそらく、古いjavascriptをリファクタリングしているので、静的に型付けされた言語は、副作用のあるコードとないコードの違いを強制できる可能性があるので、自分で付けた命名規則に頼らなければならないでしょう。

edit2:modsについては、これを主にオピニオンベースとして閉じるので、私は同意しなければなりません。私は、もしあれば、どのような慣例が一般的に使用されているのかを尋ねていました-これは誰かの定義によると、意見ではなく事実の問題です!

9
technicalbloke

コマンドとクエリの分離 に従います。値を返す関数には副作用がありません。副作用がある関数は値を返しません。

また、値が返される後に名詞や形容詞などの値を返す関数に名前を付けるのにも役立ちます。副作用がある関数は、それらが実行する効果、つまり動詞にちなんで名前を付ける必要があります。

したがって、たとえばmyArray.sort()には副作用があり、配列をソートします。したがって、何も返さず、動詞にちなんで名付けられます。一方、myArray.sorted()myArrayのソートされたコピーを返します。したがって、副作用はなく、返されるものにちなんで名前が付けられます。

参考までに、上記のアイデア(純粋関数の名詞/形容詞と副作用生成関数の動詞)は、Swift 3。

副作用に応じて関数とメソッドに名前を付ける

  • 副作用のないものは名詞句として読むべきです。
  • 副作用のある人は、命令的な動詞句として読む必要があります。

https://Swift.org/documentation/api-design-guidelines/#strive-for-fluent-usage

8
Daniel T.

基本的な問題は、副作用が型システムに取り込まれないことです。関数の命名規則の使用は、静的検証の代替としては不十分です。これを回避する方法はいくつかあります。

Haskellはモナドを使用して、コンテキスト内の副作用をキャプチャします。モナディックbind演算は、通常の関数構成演算子が純粋な関数を構成するのと同様に、不純な関数を構成します。モナドの法則により、この演算子は通常の合成と同様に機能します。

別の方法は、をコマンド完全にから分離することにより、純粋から不純を分離することです。これらは、混合できない2つのまったく異なる構文カテゴリです。式には、用語を作成できるタイプがあります。式は、定義により、割り当て可能要素に依存できません(storeへのアクセス権がありません)。コマンドには従来の意味での型がなく、値を返すことはできません。ストアを変更することによってのみ、プログラムと対話できます。

従来のタイプセーフな「関数型」言語は、これらのパラダイムのいずれにも従わない場合があることに注意してください。たとえば、OCamlとSMLは、純粋な関数と純粋でない関数を適切に区別しません。

これらのソリューションはどちらも完璧ではなく、これはまだ活発な研究分野です。

4
gardenhead

メソッドや関数の呼び出しは、コードが安全でないレベルをもたらす時間を洗い出すのに役立つため、素晴らしいアイデアのように見えます。 Joel Spolskyは彼の記事でこのアイデアをかなり掘り下げていますMaking Wrong Code Look Wronghttp://www.joelonsoftware.com/ Articles/Wrong.html )ここでは、あまり知られていないバージョンのハンガリー語表記を使用して、システム内で特定のアイデアをより透明にすることをお勧めします。

あなたが参照している言語はほぼ間違いなくSchemeです(簡単な例は http://download.plt-scheme.org/doc/html/guide/set_.html を参照してください)。私はグローバルなことは何も知りません。

Javaは、プロパティメソッドにgetおよびsetをプレフィックスとして付けて、この目的を部分的に満たしますが、LISPの世界の外で言及しているような一般的な規則(@gardenhead指摘)型システムに埋め込まれています。

主に、副作用が一般よりもさらに危険である多くの同時実行性を持つ何かを扱う場合は特に、チームのスタイルガイドラインを作成するのはかなり安全だと思います。

それが価値あるものなら何でも、私はこれをALGOL風の言語で実装するためのいくつかの方法を考えることができます。単純なものは、Spolskyによって疑似的に提案されているように、プレフィックスである可能性があります-ステートフル操作の場合はs_、ステートレス操作の場合はl_とします。

より現代的なアイデアは、単語を接頭辞または接尾辞として置くことです。多分calculateは純粋な関数ですが、mutateCalculationは不純な関数です。

最後に、懸念の分離によってこれの多くを処理する必要がある程度があります。たとえば、データベースを更新するレイヤーだけがデータベースを更新できるようにする必要があります。その場合、ステートフルレイヤーでの副作用について心配する必要があることは明らかです。

3
Michael