Entschuldigung für den Waffeltitel - wenn ich einen prägnanten Titel finden könnte, müsste ich die Frage nicht stellen.
Angenommen, ich habe einen unveränderlichen Listentyp. Es gibt eine Operation, Foo(x)
die am Ende eine neue unveränderliche Liste mit dem angegebenen Argument als zusätzliches Element zurückgibt. Um eine Liste von Zeichenfolgen mit den Werten "Hallo", "unveränderlich", "Welt" zu erstellen, können Sie Folgendes schreiben:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(Dies ist C # -Code, und ich bin am meisten an einem C # -Vorschlag interessiert, wenn Sie der Meinung sind, dass die Sprache wichtig ist. Es handelt sich nicht grundsätzlich um eine Sprachfrage, aber die Redewendungen der Sprache können wichtig sein.)
Wichtig ist, dass die vorhandenen Listen nicht durch geändert werden Foo
- also empty.Count
immer noch 0 zurückgeben.
Ein anderer (idiomatischerer) Weg, um zum Endergebnis zu gelangen, wäre:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
Meine Frage ist: Was ist der beste Name für Foo?
EDIT 3 : Wie ich später verrate, ist der Name des Typs möglicherweise nicht der richtige ImmutableList<T>
, was die Position klar macht. Stellen Sie sich stattdessen vor, TestSuite
dass es unveränderlich ist, weil das gesamte Framework, zu dem es gehört, unveränderlich ist ...
(Ende der Bearbeitung 3)
Optionen, die ich mir bisher ausgedacht habe:
Add
: häufig in .NET, impliziert jedoch eine Mutation der ursprünglichen ListeCons
: Ich glaube, dies ist der normale Name in funktionalen Sprachen, aber für diejenigen ohne Erfahrung in solchen Sprachen bedeutungslosPlus
: Mein bisheriger Favorit, das bedeutet für mich keine Mutation . Anscheinend wird dies auch in Haskell verwendet, jedoch mit leicht unterschiedlichen Erwartungen (ein Haskell-Programmierer könnte erwarten, dass er zwei Listen zusammenfügt, anstatt der anderen Liste einen einzelnen Wert hinzuzufügen).With
: im Einklang mit einigen anderen unveränderlichen Konventionen, hat aber nicht ganz die gleiche "Hinzufügung" IMO.And
: nicht sehr beschreibend.- Betreiberüberlastung für +: Ich mag das wirklich nicht so sehr; Ich denke im Allgemeinen, dass Operatoren nur auf Typen niedrigerer Ebenen angewendet werden sollten. Ich bin jedoch bereit, mich überzeugen zu lassen!
Die Kriterien, die ich für die Auswahl verwende, sind:
- Gibt den richtigen Eindruck vom Ergebnis des Methodenaufrufs (dh, es ist die ursprüngliche Liste mit einem zusätzlichen Element).
- Macht so deutlich wie möglich, dass die vorhandene Liste nicht mutiert wird
- Klingt vernünftig, wenn sie wie im zweiten Beispiel oben verkettet sind
Bitte fragen Sie nach weiteren Details, wenn ich mich nicht klar genug mache ...
EDIT 1: Hier ist meine Argumentation für die Bevorzugung Plus
zu Add
. Betrachten Sie diese beiden Codezeilen:
list.Add(foo);
list.Plus(foo);
Meiner Ansicht nach (und das ist eine persönliche Sache) ist letzteres eindeutig fehlerhaft - es ist wie das Schreiben von "x + 5;" als eine Aussage für sich. Die erste Zeile scheint in Ordnung zu sein, bis Sie sich daran erinnern, dass sie unveränderlich ist. Tatsächlich ist die Art und Weise, wie der Plus-Operator alleine seine Operanden nicht mutiert, ein weiterer Grund, warum dies Plus
mein Favorit ist. Ohne die leichte Schwierigkeit der Operatorüberladung gibt es immer noch die gleichen Konnotationen, einschließlich (für mich), dass die Operanden (oder in diesem Fall das Methodenziel) nicht mutiert werden.
EDIT 2: Gründe, warum Add nicht gefällt.
Verschiedene Antworten sind effektiv: "Gehen Sie mit Hinzufügen. Das ist, was DateTime
tut, und String
hat Replace
Methoden usw., die die Unveränderlichkeit nicht offensichtlich machen." Ich stimme zu - hier hat Vorrang. Allerdings habe ich gesehen , viele Leute nennen DateTime.Add
oder String.Replace
und erwarten Mutation . Es gibt eine Menge Newsgroup-Fragen (und wahrscheinlich SO-Fragen, wenn ich mich umschaue), die mit "Sie ignorieren den Rückgabewert von String.Replace
; Zeichenfolgen sind unveränderlich, eine neue Zeichenfolge wird zurückgegeben." Beantwortet werden .
Jetzt sollte ich die Frage subtil behandeln - der Typ ist möglicherweise keine unveränderliche Liste, sondern ein anderer unveränderlicher Typ. Insbesondere arbeite ich an einem Benchmarking-Framework, bei dem Sie einer Suite Tests hinzufügen und eine neue Suite erstellen. Es könnte offensichtlich sein, dass:
var list = new ImmutableList<string>();
list.Add("foo");
wird nichts bewirken , aber es wird viel düsterer, wenn Sie es ändern in:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
Das sieht so aus, als ob es in Ordnung sein sollte. Während dies für mich den Fehler klarer macht:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
Das bettelt nur darum:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
Im Idealfall möchte ich, dass meinen Benutzern nicht mitgeteilt werden muss, dass die Testsuite unveränderlich ist. Ich möchte, dass sie in die Grube des Erfolgs fallen. Dies ist möglicherweise nicht möglich, aber ich würde es gerne versuchen.
Ich entschuldige mich für die übermäßige Vereinfachung der ursprünglichen Frage, indem ich nur über einen unveränderlichen Listentyp spreche. Nicht alle Sammlungen sind so selbsterklärend wie ImmutableList<T>
:)