不変コレクションの非変更「追加」メソッドに最適な名前は何ですか?


229

気まずいタイトルで申し訳ありません-簡潔なタイトルを思い付くことができれば、質問する必要はありません。

不変のリストタイプがあるとします。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.Count0を返すことです。

最終結果に到達する別の(より慣用的な)方法は次のとおりです。

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:ここに好むのための私の推論ですPlusAdd。次の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>:) ほど完全に自己記述的であるとは限りません。


2
@Adam:いいえ、後者は明らかにバグがあります。彼らは両方のだ、実際に(彼らは結果に何もしないしているとして)バギー-しかし、最初はありません見て、私にバギー。
Jon Skeet、

36
猫は犬ですか?
マイケルマイヤーズ

7
Concat / Condog ...は私のために働きます!;)
gnovice

11
Uncat-ゾンビ猫になります。
Erik Forbes、

2
@Trap:APIを流動的にするという点では、これはひどいことです。
ジョンスキート

回答:


130

そのような状況では、私は通常で行きConcatます。これは通常、新しいオブジェクトが作成されていることを意味します。

var p = listA.Concat(listB);
var k = listA.Concat(item);

3
これはSystem.Linq.Enumerableが使用するものであるため、私が使用するものです-決定はすでに行われています。:)追加する単一の値を受け入れるようにIEnumerableでConcat拡張の独自のオーバーロードを定義した唯一の人物になることはできません。
ダニエルEarwicker 2009年

9
+1これは、フレームワーク内でネーミングの一貫性を維持するため正しい答えです。
Sam Harwell、

System.Linq.Enumerable(および一般にLinq)が欠落している場合を除き、Concat()は「シーケンス+シーケンス」にのみ使用され、「アイテム+シーケンス」には使用されません。「他のリストに単一の値を追加するのではなく、2つのリストを一緒に追加することを期待する可能性がある」という問題は、他の元のオプションのいずれかを使用しない理由として明示的に与えられました。
Ssswift 2018年

119

単純な理由から、私は短所を採用します。それは、まさにあなたが望んでいることを意味します。

  1. 私は、特にソースコードで、私が言っていることを正確に話すのが大好きです。初心者は、短所の定義を1回だけ参照する必要がありますが、それを数千回読んで使用します。長期的には、初期費用が少し高くても、一般的なケースを容易にするシステムを使用する方が良いと思います。

  2. FPの経験がない人にとっては「無意味」であることは、実際には大きな利点です。ご指摘のとおり、他のすべての単語にはすでに何らかの意味があり、その意味はわずかに異なるかあいまいです。新しい概念に新しい単語(またはこの場合は古い単語)が必要です。私は誰かが間違ってAddの機能を知っていると想定するのではなく、Consの定義を調べなければなりません。

  3. 関数型言語から借用した他の操作は、元の名前を維持することが多く、明らかな大災害はありません。「map」と「reduce」の同義語を考えて、FPS以外のユーザーには馴染みのあるプッシュを目にしたことはありません。

(完全な開示:私はLispプログラマーなので、短所の意味はすでに知っています。)


16
ただし、「testSuite」と入力した場合、発見しやすさが重要であることを忘れないでください。そしてメソッドのリストを見て、正しいことを示唆するメソッドを見たいのですが。私はおそらく、私が望むものである犯罪に対して、無意味な(私にとって)名前を検索しません。
Jon Skeet、

33
私がぎくしゃくしていると感じた場合は、メッセージAdd = "Use Cons to prepend to an ImmutableList"で例外をスローするだけのメソッドAddを作成します。:-)
ケン

2
名前が何であるかを説明する数行のコメントを読んで、たとえばAbelson&Sussmanの「コンピュータプログラムの構造と解釈」を参照しても、誰も殺しません。
John R. Strohm、2010

16
従来、短所は末尾ではなく先頭に追加されていました。したがって、これは、説明されているメソッドの誤解を招く可能性のある名前です。
walkytalky 2010

16
次の機能しないプログラマーにクリックまたは3 ... en.wikipedia.org/wiki/Consを保存するために、「construct」という単語から、「to cons x into y」という表現は、( cons xy)
Myster

59

実際、私はAnd、特に慣用的な方法で好きです。特に、Emptyリストの静的な読み取り専用プロパティがあり、おそらくコンストラクターをプライベートにして、常に空のリストからビルドする必要がある場合に、私はそれが好きです。

var list = ImmutableList<string>.Empty.And("Hello")
                                      .And("Immutable")
                                      .And("Word");

空のアイデアが好きです。それでもまだ確信はありません。それはほんの少しおかしいです。
Jon Skeet、

自然言語で物事のリストを作成することについて、私はどのように考えているのでしょうか。大声で読むと、AddやPlusよりも直感的です。「list」は空のリストで、「Hello」と「Immutable」と「Word」です。しかし、それだけでは明確ではないことに同意します。
tvanfosson 2009

52

私が命名法で混み合っているときはいつでも、私はインターウェブにぶつかった。

thesaurus.comは "add"に対してこれを返します:

定義:隣接、増加; さらにコメントする

同義語: affix、annex、ante、append、augment、beef up、boost、build up、charge up、continue、cue in、figure、flesh out、heat up、hike、hike up、hitch on、フックオン、フックアップwith、include、jack up、jazz up、join join、pad、parlay、piggyback、plug into、poure on it、reply、run up、さらに言う、slap on、snowball、soup up、speed up、spike、step up、サプリメント、甘く、タックオン、タグ

の音Adjoin、またはもっと単純に好きですJoin。それはあなたがしていることですよね?この方法は、他ImmutableList<>のの参加にも適用できます。


1
「結合」も好きですが、ほとんどの場合、2つのオブジェクトを結合すると1になります。この場合、2つのオブジェクトを結合すると、実際には新しいオブジェクトが作成されます。
アウトロープログラマ

1
.NET、Perl、PHP、またはVBScriptで、Joinがミューテーションを意味するケースについては知りません。AとBが結合してCを作成する設計です。Cは常に新しいエンティティです。
スポールソン2009

私は参加が好きで、thesaurus.comに完全に同意します:)名前が疑わしいときはいつでも使用してください。
Skurmedel、2009年

var suite = new TestSuite <string、int>().Join(x => x.Length);
Sly Gryphon

3
Piggybackと一緒に行きましょう。またはHookUpWith。
Chris Marasti-Georg、2009

48

個人的には、.With()が好きです。オブジェクトを使用している場合は、ドキュメントまたはコードのコメントを読んだ後、それが何をするのかが明確になり、ソースコードで問題なく読み取れます。

object.With("My new item as well");

または、「それに沿って」を追加します.. :)

object.AlongWith("this new item");

+1。「WITH」は、同じことを行うSETLの挿入演算子です。SETLがそれを使用する場合、それは正しい必要があります:-)
finnw

1
Bah ...もうVBを使うのは誰?:)ええと。Opps ..それは大声でしたか?heh ..しかし、いいえ、すべての真剣に、それが私が "AlongWith"を検討した理由です、それはVBの問題を取り除くでしょう。彼がこれと一緒に進むことができる方法は約100万しかありません...つまり、object.Plus()、またはObject.ExistingPlus()...などの非常識な方法でさえも...それは彼のいまいましい質問です投稿、しかし…heh ..
LarryF 2009年

33

私はBclExtrasのすべての不変コレクションにAddを使用することになりました。その理由は、簡単に予測できる名前だからです。型の名前の先頭にImmutableが付いているので、Addとmutating addを混同している人々についてはそれほど心配していません。

しばらくの間、私は短所と他の機能的なスタイル名を考えました。彼らはあまり知られていないので、結局私はそれらを割り引きました。確かに関数型プログラマは理解するでしょうが、彼らは大多数のユーザーではありません。

他の名前:あなたは言及しました:

  • プラス:私はこれを望んでいます/洗っています。私にとっては、これはAddとは異なり、非変異操作であることを区別しません
  • あり:VBで問題が発生します(意図的なしゃれ)
  • オペレーターの過負荷:発見可能性が問題になる

私が検討したオプション:

  • 連結:文字列は不変であり、これを使用します。残念ながら、それは最後に追加するのに本当に良いだけです
  • CopyAdd:何をコピーしますか?ソース、リスト?
  • AddToNewList:たぶん、Listに適しています。しかし、コレクション、スタック、キューなどについてはどうでしょうか。

残念ながら、実際には

  1. 間違いなく不変の操作
  2. ほとんどのユーザーが理解できる
  3. 4語未満で表現可能

リスト以外のコレクションを検討すると、さらに奇妙になります。たとえばスタックを見てください。初年度のプログラマーでも、スタックにはPush / Popのメソッドのペアがあることがわかります。ImmutableStackを作成して完全に異なる名前を付け、Foo / Fopと呼ぶと、コレクションを使用するための作業が追加されただけです。

編集:プラス編集への応答

あなたがプラスでどこへ行くのか分かります。より強力なケースは、実際には削除のマイナスになると思います。以下を見たとしたら、プログラマは何を考えているのでしょうか。

list.Minus(obj);

プラス/マイナスまたは新しいペアリングで私が抱えている最大の問題は、やり過ぎのように感じることです。コレクション自体には、識別可能な名前である不変の接頭辞がすでにあります。なぜ、Immutableプレフィックスが既に行ったのと同じ区別を追加することを意図した語彙を追加することによって、さらに進んでください。

呼び出しサイトの引数を見ることができます。単一の表現の観点からそれを明確にします。しかし、関数全体のコンテキストでは、それは不要に思えます。

編集2

String.ConcatとDateTime.Addに間違いなく混乱していることに同意してください。私は何人かの非常に優秀なプログラマーがこの問題にぶつかるのを見てきました。

ただし、ImmutableListは別の引数だと思います。プログラマにとってそれを不変として確立するStringまたはDateTimeについては何もありません。他のソースを介して不変であることを単に知っておく必要があります。したがって、混乱は予想外ではありません。

名前がその動作を定義しているため、ImmutableListにはその問題はありません。イミュータブルが何であるかを人々は知らない、と私は思うかもしれません。私は確かに大学の2年目までそれを知りませんでした。ただし、追加する代わりに、選択した名前で同じ問題が発生します。

編集3: TestSuiteのような不変であるが単語を含まない型はどうですか?

これは、新しいメソッド名を発明するべきではないという考えを思い起こさせると思います。つまり、並列処理を容易にするために、型を不変にするという明確な動機があるからです。コレクションのメソッド名の変更に重点を置く場合、次のステップは、不変である、使用するすべての型のメソッド名の変更です。

代わりに、タイプを不変として識別可能にすることに焦点を当てるほうが、より価値のある取り組みになると思います。そうすれば、そこにあるすべての変異メソッドパターンを再考することなく、問題を解決できます。

では、TestSuiteを不変として特定するにはどうすればよいでしょうか。今日の環境ではいくつかの方法があると思います

  1. 不変のプレフィックス:ImmutableTestSuite
  2. 免疫力のレベルを説明する属性を追加します。これは確かに発見されにくい
  3. 他にはあまりありません。

私の推測/希望は、開発ツールが不変の型を視覚だけで簡単に識別できるようにすることでこの問題の手助けを始めることです(異なる色、より強いフォントなど...)。しかし、すべてのメソッド名を変更するのではなく、それが答えだと思います。


質問にプラスよりもプラスを優先する理由を追加しました。その理由についてのコメントを歓迎します。私はばかげているという考えに本当にオープンです。
Jon Skeet、

@JaredPar:タイプがTestSuiteと呼ばれる場合はどうですか?
Jon Skeet、

編集3のために別の+1を与えたいのですが、明らかにできません。私はまだいないよ- (私はおよそ理由が容易になり、コードにその不変のリードを信じている。私の場合は、並列処理を取得しようとしていないよ)、かなりの追加が進むべき道であると確信しますが、ここでの回答でのサポート説得力があります。
Jon Skeet、

この質問を職場での会話に落とすことができれば、それも素晴らしいことです。私はC#リストで議論を始めたので、何人かの同僚が既に関与しているかもしれません。Googleでも社内で質問する可能性があります...
ジョンスキート

@ジョン、私はこの質問を職場で捨てるのに良い場所を知っていると思います:)
JaredPar 2009

27

これは、+オペレーターに過負荷をかけることが許容されるまれな状況の1つかもしれません。数学用語では、それが+何かの終わりに何かを追加しないことを知っています。常に2つの値を組み合わせ、新しい結果値を返します。

たとえば、あなたが言うとき、それは直感的に明らかです

x = 2 + 2;

xの結果の値は4ではなく22です。

同様に、

var empty = new ImmutableList<string>();
var list1 = empty + "Hello";
var list2 = list1 + "immutable";
var list3 = list2 + "word";

各変数が何を保持するかを明確にする必要があります。最後の行で変更されてlist2いないことは明らかですが、代わりに「word」をに追加した結果が割り当てられています。list3list2

それ以外の場合は、関数にPlus()という名前を付けるだけです。


整数(たとえば)または整数の別のリストを合法的に追加できる一般的なリストがある場合はどうでしょうか。次に、この+の使用は連結と競合します。
finnw 2009年

@finnw:あなたの意見はわかりません。リストでは、1つまたは複数の要素を追加する場合でも、常に+が追加を意味することを期待しています。
リザードに請求する

4
再利用可能なAPIの場合、演算子のオーバーロードなしで言語のクラスを誰かが使用している場合に備えて、名前付きメソッドも用意することをお勧めします。
ニール、

「1つまたは複数の要素を追加するかどうか」-リストを単一の要素として追加する場合はどうでしょうか。すなわち、[1] + 2 = [1,2]しかし[1] + [2] = [1,[2]]。あなたが示唆しているのは、一貫性のない行動です。これがおそらく、Pythonがこの方法で1つの要素を追加することを許可しない理由です。
mpen

まあ、C#のような静的に型付けされた言語では、リスト要素のタイプが何であるか、リストのリストであるか要素のリストであるかを判別できるため、タイプを使用して、リストである1つの要素を追加するか連結するかを決定できます。 2つのリスト。
Dobes Vandermeer 2014年

22

できるだけ明確にするために、wordier CopyAndAddなどを使用することをお勧めします。


ただし、すべての不変コレクションにコピーを追加する必要はありません。不変のツリーについて考えてみましょう。新しいノードが必要で、既存のツリーをリーフとして使用できます。
JaredPar 2009

ところで、私はあなたのプロフィールを読んで、次に順番に年齢を読みました、そしてあなたが何歳であるかについて簡単に驚きました。その後まもなく正気が始まった。
JaredPar 2009

最初のコメントについて:私はめったにそのような考えが私に起こらなかったほど木を使用します。それは良い点です。
マイケル・マイヤーズ

2番目のコメントについて:私は告白します、私はバッジのためにそれをしました!年齢を明かしたくないだけです。(私は実際にはあなたより若いですが、必要に応じて私はかなり古臭い昔ながらの人を演じることができます。そして年齢が89と表示されているのは私だけではありません。)
マイケルマイヤーズ

不変のツリーの引数は強力なものであり、良い点です。したがって、EquivalentReferenceWithAdded(x)はその議論に対抗しますが、愚かに聞こえ、推測するのは困難です。
TheBlastOne 2011

21

本当に冗長だと感じた場合は、Extend()または多分ExtendWith()と呼びます。

拡張とは、変更せずに何かを他のものに追加することを意味します。これは拡張メソッドの概念に似ているので、これはC#で非常に関連する用語だと思います。クラス自体に「触れる」ことなく、クラスに新しいメソッドを「追加」します。

それ以外の場合で、元のオブジェクトをまったく変更しないことを本当に強調したい場合は、Get-のような接頭辞を使用するのは避けられないように見えます。


1
それでも、ちょっと基本オブジェクトに何かをすることを意味します。
混沌

18

追加()、追加()

不変オブジェクトの操作には過去形を使いたいです。これは、元のオブジェクトを変更していないという考えを伝えており、見たときに簡単に認識できます。

また、メソッドの名前の変更は、現在存在する動詞であることが多いため、不変のメソッド名が必要なほとんどのケースに当てはまります。たとえば、不変スタックには、「プッシュ」および「ポップ」メソッドがあります。


1
Pythonもこの規則を使用します。たとえば、組み込み関数reverse()とsorted()です。
Joe

18

私はmmyersのCopyAndAddの提案が好きです。「突然変異」のテーマに沿って、Bud(無性生殖)、GrowReplicate、またはEvolveを使用できますか?=)

編集:私の遺伝的テーマを続けるために、Procreateはどうですか?以前のオブジェクトに基づいて新しいオブジェクトが作成され、何か新しいものが追加されたことを意味します。


14

これはおそらくストレッチですが、Rubyでは区別のために一般的に使用される表記がありaddます。変化しません。add!変異します。これがプロジェクトに蔓延する問題である場合は、それも行うことができます(アルファベット以外の文字を使用する必要はありませんが、一貫して表記法を使用して変異/非変異メソッドを示します)。


+1。これは言語によって強制されていませんが、慣例として合意されています。私はすきです。
オマ


13

たぶん、2つの操作を1つにしたいという事実が混乱の原因かもしれません。それらを分離しないのはなぜですか?DSLスタイル:

var list = new ImmutableList<string>("Hello");
var list2 = list.Copy().With("World!");

Copy元のリストの変更可能なコピーである中間オブジェクトを返します。With新しい不変リストを返します。

更新:

ただし、中間で変更可能なコレクションを用意することは、良い方法ではありません。中間オブジェクトはCopy操作に含まれている必要があります。

var list1 = new ImmutableList<string>("Hello");
var list2 = list1.Copy(list => list.Add("World!"));

これで、Copy操作はデリゲートを受け取り、変更可能なリストを受け取るため、コピーの結果を制御できます。要素の削除やリストの並べ替えなど、要素を追加するだけではありません。ImmutableListコンストラクターで使用して、中間の不変リストなしで初期リストを組み立てることもできます。

public ImmutableList<T> Copy(Action<IList<T>> mutate) {
  if (mutate == null) return this;
  var list = new List<T>(this);
  mutate(list);
  return new ImmutableList<T>(list);
}

これで、ユーザーが誤って解釈する可能性はなくなり、自然に成功の穴に落ちます。

さらに別の更新:

可変リストの言及がまだ気に入らない場合は、それが含まれている場合でも、コピー操作がリストを変換する方法を指定する、またはスクリプトする仕様オブジェクトを設計できます。使い方は同じです:

var list1 = new ImmutableList<string>("Hello");
// rules is a specification object, that takes commands to run in the copied collection
var list2 = list1.Copy(rules => rules.Append("World!"));

これで、ルール名を使用してクリエイティブになりCopy、サポートする機能のみを公開できますIList。の機能全体を公開することはできません。

チェーンを使用する場合は、妥当なコンストラクターを作成できます(もちろん、チェーンは使用しません)。

public ImmutableList(params T[] elements) ...

...

var list = new ImmutableList<string>("Hello", "immutable", "World");

または、別のコンストラクタで同じデリゲートを使用します。

var list = new ImmutableList<string>(rules => 
  rules
    .Append("Hello")
    .Append("immutable")
    .Append("World")
);

これは、rules.Appendメソッドがを返すことを前提としていますthis

これは、最新の例では次のようになります。

var suite = new TestSuite<string, int>(x => x.Length);
var otherSuite = suite.Copy(rules => 
  rules
    .Append(x => Int32.Parse(x))
    .Append(x => x.GetHashCode())
);

@Jordao:この種の構成は、はるかに単純な初期化形式につながるからです。1つだけ必要なのに、なぜ2つの別々の変数があるのですか?同様に、私は変更可能なコピーを作成したくありません-IMOのほうが推論しやすいコードにつながるため、すべてを変更できないようにしたいと思います。
Jon Skeet、2010

これらのすべては、「プラス」などよりも扱いにくいです。ミューテーションに関連するアイデアをありがとうございますが、私は「不変に保つ」アプローチを確実に好みます。
Jon Skeet

おそらく、操作の実際のセマンティクスが何であるかについては、常に誤った解釈があるでしょう。仕様オブジェクトのルートをたどる場合、(少なくとも外部的には)変更は行われず、オブジェクトは新しい不変オブジェクトがどのように見えるかを指定するだけです。あなたが持っているのは、ある不変オブジェクトから別のオブジェクトへと進む操作であり、それはコピーと呼ばれているので、誤解する余地はありません。
ジョルダン2010

あなたのために働くだろう唯一の名前がなどCopyAndAppend、CopyAndAdd、のような化合物名、ように見える
ジョルダン

1
私は実際、不変コレクションのAPIとして、このアプローチ(すべての編集を含む)の素晴らしさを増しています。ただし、このアプローチをConcatなどのデフォルト仕様のヘルパーメソッドと組み合わせると、両方の長所が得られると私は主張します。

11

いくつかのランダムな考え:

  • ImmutableAdd()
  • Append()
  • ImmutableList <T>(ImmutableList <T> originalList、T newItem)コンストラクタ

1
ImmutableAddの+1。Append(変更が多すぎるStringBuilder.Appendに非常に似ている)に熱心ではなく、コンストラクターのバージョンはチェーンの面で苦痛です。
Jon Skeet、

10

C#のDateTimeはAddを使用します。それでは、なぜ同じ名前を使用しないのですか?クラスのユーザーがクラスが不変であることを理解している限り。


DateTime.Addはユーザーを混乱させることが知られていると主張しますが、優先順位が高いことに同意します。
Jon Skeet、

1
文字列を変更するメソッドが新しい開発者を混乱させるように。しかし、すぐに誰もが「文字列は不変」であることを知る
タンディー

9

私があなたが表現しようとしている重要なことは、非順列であるため、おそらく、CopyWith()やInstancePlus()のような生成的な単語が含まれていると思います。


9

英語では、「追加」と同じことを意味する動詞を使用している間、紛れもない方法で不変性を暗示することはできないと思います。「プラス」はほとんどそれを行いますが、人々はまだ間違いを犯すことができます。

ユーザーがオブジェクトを変更可能なものと間違えるのを防ぐ唯一の方法は、オブジェクト自体の名前またはメソッドの名前を使用して明示的にすることです( "GetCopyWith"などの詳細オプションと同様に、または「CopyAndAdd」)。

だから、お気に入りの「プラス」を使いましょう。


9

まず、興味深い出発点:http : //en.wikipedia.org/wiki/Naming_conventions_(programming) ...特に、下部にある「関連項目」リンクを確認してください。

私はプラスまたはアンドのどちらかに賛成です。

PlusとAndは、両方とも語源の数学に基づいています。したがって、どちらも数学演算を意味します。どちらも、値に解決される可能性のある式として自然に読み取られる式を生成します。これは、戻り値を持つメソッドに適合します。 And追加の論理的な意味合いを持っていますが、どちらの単語もリストに直感的に適用されます。 Addオブジェクトに対して実行されるアクションを示します。これは、メソッドの不変のセマンティクスと競合します。

どちらも短く、これは操作の原始性を考えると特に重要です。単純で頻繁に実行される操作は、短い名前に値します。

不変のセマンティクスを表現することは、コンテキストを介して行うことを好むものです。つまり、このコードブロック全体が機能的な感じを持っていることを単に暗示するだけです。すべてが不変であると仮定します。しかし、それは私だけかもしれません。私はルールよりも不変性を好む。それが行われた場合、同じ場所で多く行われます。可変性は例外です。


8

Chain()またはAttach()はどうですか?


1
添付は確かに変異しているように聞こえます。おそらくWithAttachedの方が賢明でしょうが、上記で説明したWithAddedに非常に近いです。
TheBlastOne 2011

これを使って何をしようとしているのかを説明するときに「連鎖」が何度も言及されているのはおかしいです。(5回)、提案として提供されていません!それはvisualthesaurus.com私がを検索したときに最初に思いついた(所属なし)concatenate
cod3monk3y 2014年

7

私はプラス(とマイナス)を好みます。それらは簡単に理解でき、よく知られた不変の型(数値)を含む操作に直接マッピングされます。2 + 2は2の値を変更しません。同じように不変の新しい値を返します。

その他の可能性:

スプライス()

Graft()

Accrete()


6

どの程度メイトmateWith、または性交遵守人のために、。哺乳類の繁殖に関しては、一般的に不変であると考えられています。

ユニオンもそこに捨てるつもりです。SQLから借用。


2
ユニオンの場合は+1。しかし、私はそれを集合論から直接借りています。:-)
Christoffer Lette、

SQLはその用語の多くを集合論から得ていませんか?
Jason D

1
また、Unionは区別を意味します。重複を含める場合(少なくともTSQLの場合)、Union Allを明示的に使用する必要があります。

6

どうやら私はこの質問に答えた最初のObj-C / Cocoaの人です。

NNString *empty = [[NSString alloc] init];
NSString *list1 = [empty stringByAppendingString:@"Hello"];
NSString *list2 = [list1 stringByAppendingString:@"immutable"];
NSString *list3 = [list2 stringByAppendingString:@"word"];

これでコードゴルフゲームに勝つことはできません。


1 [object]By[Verb]ing[Object]:メソッドの接頭辞は、単純とは対照的に、新しい文字列が返されることを意味し[verb][Object]:、インプレースオブジェクトを変異させることになります。
Dave DeLong、2011年

3
+1。冗長性(自己文書化)に対する人々の嫌悪感がわかりません。
ハトフィンチ2011

5

「追加」または「プラス」は問題ないと思います。リスト自体の名前は、リストの不変性を伝えるのに十分でなければなりません。


リストではなく、テストスイートです。
tstenner 2010

5

たぶん、インスタンスを変更するのではなく、コピーを作成してそれに要素を追加することを覚えている単語があります(「連結」など)。しかし、私は他の行動のためにそれらの言葉にいくらか対称性を持たせることも良いことだと思います。「削除」のように、「連結」のように同じ種類だと思う類似の単語は知りません。「プラス」は少し奇妙に聞こえます。非数値のコンテキストで使用されるとは思いません。しかし、それは私の英語以外の背景からも来るかもしれません。

多分私はこのスキームを使うでしょう

AddToCopy
RemoveFromCopy
InsertIntoCopy

しかし、私が考えると、これらには独自の問題があります。与えられた引数に何かを削除したり、何かを追加したりすることができます。まったくわからない。これらの単語は連鎖においてもうまく機能しないと思います。入力するには文字が多すぎます。

多分私は普通の「追加」と友達も使うだろう。数学での使い方が好き

Add 1 to 2 and you get 3

まあ、確かに、2は2のままで、新しい番号を取得します。これは、リストと要素ではなく、2つの数値ですが、いくつかの類似点があると思います。私の意見でaddは、必ずしも何かを変異させるという意味ではありません。私は確かに、add、返された新しいオブジェクトを使用しないとバグがないように見えるです。しかし、「追加」以外の名前を使用するという考えについてもしばらく考えましたが、「うーん、私はドキュメントを見て何を知る必要があるでしょうか」その名前は、私が「追加」と呼んでいると期待するものとは異なるためです。litbからこれについていくつかの奇妙な考えがありましたが、それがまったく理にかなっているかどうかはわかりません:)


しかし、不変のコレクションでは常にコピーが必要なわけではありません。たとえば、二分木を取ります。新しいルートを追加する場合、コピーする必要はありません。葉の1つが古いツリーである新しい値が必要です
JaredPar 2009

KISS-名前付けに実装の詳細が含まれ始めた場合、すべてのメソッド名が過度に長くなります。「追加」は十分に簡単で、その仕事をします。
mP。

1
@mP:繰り返しになりますが、「実装の詳細」というフレーズは不適切だと私が思う方法で使用しています。リンクされたリストであるか、内部の配列であるかは、実装の詳細です。APIを変更せずに実装を変更できました。不変の側面は実装の詳細ではありません
Jon Skeet、

1
正しい。JaredParですが、実際にツリーをコピーするか、既存のツリーをそのまま使用して、返される新しいツリーのリーフとして使用するかどうかも重要ではないと思います。つまりこれは実装の詳細にすぎません。これは、Javaの文字列クラスの部分文字列操作と同じです(私は信じています)。
ヨハネスシャウブ-litb 2009


5

私はPlus()Minus()または、あるいはIncluding()Excluding()で合理的である暗示不変の行動を。

ただし、命名の選択によって誰にとっても完全に明確になることは決してないので、良いxml docコメントは非常に長い道のりとなると私は個人的に信じています。VSは、IDEでコードを書くときに、これらをあなたの目の前に投げます-それらは無視するのが難しいです。


4

Append -なぜなら、 System.Stringメソッドのインスタンスを変異させることを示唆しているが、そうではないてください。

または私はかなり好きAfterAppendingです:

void test()
{
  Bar bar = new Bar();
  List list = bar.AfterAppending("foo");
}

以前のDateTime引数と同様に、多くのプログラマー文字列メソッドが何かを行うことを期待しているという事実がなければ、優先順位に同意します。文字列は不変であることを(ときどき繰り返し)伝えなければなりません。私はクライアントの開発者を成功の穴に誘いたいと思います:)
Jon Skeet

ますます追加が好きです。コレクションを変更するのではなく、コレクションに参加することを区別します。

4

list.CopyWith(element)

Smalltalkと同様に:)

またlist.copyWithout(element)、要素のすべての出現を削除します。これは、list.copyWithout(null)未設定の要素を削除するために使用する場合に最も役立ちます。


3

より良い名前の利点を見ることができるので、私はAddに行きますが、問題は、それが理にかなっている場合、クラスをかなりなじみのないものにする他のすべての不変の操作に対して異なる名前を見つけることです。


はい、あなたの言うとおりです。私はまだプラスを好むと思いますが、それは考慮に値する点です。
Jon Skeet、

ジョン、ありがとう。私はあなたのフレームワークを使用することを楽しみにしています。私はそれについて読んだだけで、とてもよさそうだ。再度、感謝します。
Joan Venge、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.