副作用がある関数の命名規則?[閉まっている]


9

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

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

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

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


1
これは言語間で異なる可能性が高く、非常に意見指向である可能性があります。
David Arno

1
たとえば、Scalaの規則は、副作用がない限り、括弧のないメソッド(プロパティのように)を宣言することです。しかし、私が知っている他の言語でこれを使用することはできません。感嘆符は私には恐ろしいようです。そのシンボルには他にも多くの使い方があり、気が散るメソッドをマークするために使われているのがわかります。
Robert Harvey

2
@RobertHarvey Schemeはその規則を使用する言語であり、変数の状態を変更する演算子が存在するため、規則が存在すると思います!(メモリが機能する場合、その演算子なしで変数の状態を変更することは構文的に有効ではありません。 )、そのため、実際にはその言語ではかなり賢明な規則です
16年

3
@Servy標準スキーマはset!、変数を変更するためのものですが、スタンドアロンの!演算子はありません。有効な識別子が何であるかについての制限がほとんどないため、Lispには識別子に記号を使用して意味を伝える歴史があるため、この規則が存在します。Lispはマクロとドメイン固有の言語に重点を置いているため、制限はありません。
Jack

1
Rubyも!規則を使用しています(例:downcasedowncase!)。ただし、「副作用」よりも「危険」の方が一般的です。
Andrew

回答:


8

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

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

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

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

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

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

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


4

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

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

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

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

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


haskellにもunsafePerformIO
jk

Haskellにはあまり詳しくありません。ほとんどの安全な言語は、最後の手段として型システムを破壊する方法を提供します。D:また、ユーザー名は、私はあなたが真剣に言う何でも取るために懸命にそれを作る
gardenhead

@jk unsafePerformIOは、このコンテキストでは安全に無視できます。これは通常のコードで使用することを意図していないエスケープハッチであり、重要な警告と警告が付属しています。とにかく、副作用のあるコードでは使用しないでください。
アンドレスF.

@AndresF。私のポイントは、unsafe *はHaskellの安全でないものの命名規則であることです。これは、それ自体が副作用を実行することを意味しますが、ユーザーコードではなく実装自体によってのみ使用されます
jk。

3

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

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

Javaはプロパティメソッドに接頭辞を付けgetsetこの目的を部分的に果たしますが、型システムに組み込まれていない(@gardenheadが指摘したように)Lispの世界の外であなたが言及している種類の一般的な規則については、私は本当に知りません。

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

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

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

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


ご回答ありがとうございます。理想的な世界では、これは主に懸念の分離によって処理されるべきであることに同意します。命名規則の私の主な使用例は、必ずしも優雅さとベストプラクティスを念頭に置いて作成されたわけではない古いコードを選択してリファクタリングすることです。(多分、時には自分で背中の日に私は宗教を持って前に!)
technicalbloke

ああ、そのJoel Spolskyの記事は素晴らしいです。リンクをありがとう!
Technicalbloke
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.