気まずいタイトルで申し訳ありません-簡潔なタイトルを思い付くことができれば、質問する必要はありません。
不変のリストタイプがあるとします。Foo(x)
最後に追加の要素として指定された引数を持つ新しい不変のリストを返す操作があります。したがって、値が「Hello」、「immutable」、「world」の文字列のリストを作成するには、次のように記述します。
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(これはC#コードであり、言語が重要だと思う場合は、C#の提案に最も興味があります。これは基本的に言語の問題ではありませんが、言語のイディオムは重要かもしれません。)
重要なことは、既存のリストはによって変更されないFoo
ため、empty.Count
0を返すことです。
最終結果に到達する別の(より慣用的な)方法は次のとおりです。
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
私の質問は、Fooの最高の名前は何ですか?
編集3:後で明らかにするように、型の名前は実際にImmutableList<T>
はとは限らないため、位置が明確になります。代わりに、それがTestSuite
不変であることを想像してください。それが含まれているフレームワーク全体が不変だからです...
(編集終了3)
これまでに思いついたオプション:
Add
:.NETで一般的ですが、元のリストの変更を意味しますCons
:これは関数型言語では通常の名前だと思いますが、そのような言語の経験がない人には無意味ですPlus
:これまでのところ私のお気に入り、それは私に突然変異を意味するものではありません。どうやらこれはHaskellでも使用されているようですが、期待が少し異なります(Haskellプログラマーは、単一の値を他のリストに追加するのではなく、2つのリストを一緒に追加することを期待するかもしれません)。With
:他の不変の慣例と一致していますが、IMOとまったく同じ「追加機能」はありません。And
:あまり説明的ではない- +の演算子のオーバーロード:本当にこれが好きではありません。一般に、演算子は下位レベルのタイプにのみ適用する必要があると思います。でも、私は説得されても大丈夫です!
私が選択に使用している基準は次のとおりです。
- メソッド呼び出しの結果の正しい印象を与える(つまり、追加の要素を含む元のリストである)
- 既存のリストを変更しないことを可能な限り明確にする
- 上記の2番目の例のように連結すると妥当な音
はっきりしない場合は、詳細を尋ねてください...
EDIT 1:ここに好むのための私の推論ですPlus
しAdd
。次の2行のコードを検討してください。
list.Add(foo);
list.Plus(foo);
私の見解では(これは個人的なことですが)後者は明らかにバグがあります-「x + 5;」と書くようなものです。独自のステートメントとして。最初の行は、不変であることを思い出すまで、問題ないように見えます。実際、プラス演算子自体がオペランドを変更しない方法Plus
が、私のお気に入りのもう1つの理由です。演算子のオーバーロードのわずかな煩わしさがなくても、同じ意味合いを示します。これには、(私にとっては)オペランド(またはこの場合はメソッドターゲット)を変更しないことが含まれます。
編集2:追加を好まない理由。
様々な答えが効果的です:「追加と行く何が。DateTime
ない、とString
ありReplace
不変性は明らかにしない方法などを。」同意します-ここに優先順位があります。しかし、私はたくさんの人が電話をかけDateTime.Add
たりString.Replace
、突然変異を期待したりするのを見てきました。「あなたはの戻り値を無視しているString.Replace
;文字列は不変であり、新しい文字列が返される」と答えられるたくさんのニュースグループの質問(そしておそらく私が調べればSOの質問)があります。
さて、私は質問の微妙さを明らかにする必要があります-タイプは実際には不変のリストではなく、別の不変のタイプであるかもしれません。特に、スイートにテストを追加して新しいスイートを作成するベンチマークフレームワークに取り組んでいます。それは明らかかもしれません:
var list = new ImmutableList<string>();
list.Add("foo");
何かを達成するために行くが、それはなっていない多くのあなたがそれを変更したときmurkier:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
大丈夫なようです。一方、これは間違いをより明確にします。
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
それはただ物乞いです:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
理想的には、テストスイートが不変であることをユーザーに通知する必要がないようにしたいと思います。私は彼らに成功の落とし穴に落ちて欲しいです。これはできないかもしれませんが、試してみたいと思います。
不変のリスト型についてのみ話し、元の質問を単純化しすぎたことをお詫びします。すべてのコレクションがImmutableList<T>
:) ほど完全に自己記述的であるとは限りません。