ふざけたタイトルで申し訳ありません。簡潔なタイトルを思いつくことができれば、質問する必要はありません。
不変のリスト型があるとします。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# の提案に最も関心があります。基本的に言語の問題ではありませんが、言語のイディオムは重要かもしれません。)
重要なことは、既存のリストは変更されないということです。つまり、 0 を返します。Fooempty.Count
最終結果に到達する別の (より慣用的な) 方法は次のとおりです。
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
私の質問は次のとおりです。Foo に最もふさわしい名前は何ですか?
編集 3 : 後で明らかにするように、型の名前は実際には ではない可能性があるためImmutableList<T>、位置が明確になります。代わりに、それがTestSuite含まれているフレームワーク全体が不変であるため、それが不変であると想像してください...
(編集3の終わり)
これまでに思いついたオプション:
Add: .NET では一般的ですが、元のリストの変更を意味しますCons:これは関数型言語の通常の名前だと思いますが、そのような言語の経験がない人には意味がありませんPlus:これまでのところ私のお気に入りです。私にとって突然変異を意味するものではありません。どうやらこれはHaskell でも使用されているようですが、少し異なる期待があります (Haskell プログラマーは、1 つの値を他のリストに追加するのではなく、2 つのリストを一緒に追加することを期待するかもしれません)。With: 他のいくつかの不変の規則と一致していますが、IMO とまったく同じ「追加性」はありません。And: あまり説明的ではありません。- + の演算子のオーバーロード: 私はこれがあまり好きではありません。一般に、演算子は下位レベルの型にのみ適用する必要があると思います。私は説得されても構わないと思っています!
私が選ぶ基準は以下の通りです。
- メソッド呼び出しの結果の正しい印象を与えます (つまり、余分な要素を持つ元のリストです)。
- 既存のリストを変更しないことを可能な限り明確にします
- 上記の 2 番目の例のように連鎖すると妥当に聞こえます
私が十分に明確にしていない場合は、詳細を尋ねてください...
EDIT 1:を好む理由は次のとおりPlusですAdd。次の 2 行のコードを検討してください。
list.Add(foo);
list.Plus(foo);
私の見解では (これは個人的なことですが)、後者は明らかにバグがあります。「x + 5;」と書くようなものです。独自のステートメントとして。最初の行は問題ないように見えますが、不変であることを思い出すまでは。実際、プラス演算子自体がそのオペランドを変更しない方法Plusは、私のお気に入りのもう 1 つの理由です。演算子のオーバーロードのわずかな不快感がなくても、(私にとっては) オペランド (またはこの場合はメソッド ターゲット) を変更しないことを含む同じ意味合いが得られます。
編集 2: Add が気に入らない理由。
さまざまな答えが効果DateTime的StringですReplace。同意します - ここには優先順位があります。DateTime.Addしかし、多くの人がorString.Replaceを呼び出して Mutation を期待しているのを見てきました。たくさんのニュースグループの質問 (そして、掘り下げてみるとおそらく SO の質問) があり、「あなたは の戻り値を無視していますString.Replace。文字列は不変であり、新しい文字列が返されます。」と答えています。
ここで、質問の微妙な点を明らかにする必要があります。型は実際には不変リストではなく、別の不変型である可能性があります。特に、テストをスイートに追加すると、新しいスイートが作成されるベンチマーク フレームワークに取り組んでいます。次のことは明らかかもしれません。
var list = new ImmutableList<string>();
list.Add("foo");
何も達成するつもりはありませんが、次のように変更すると、より暗くなります。
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>:)