Ci scusiamo per il titolo waffly - se potessi trovare un titolo conciso, non avrei dovuto porre la domanda.
Supponiamo che io abbia un tipo di elenco immutabile. Ha un'operazione Foo(x)
che restituisce un nuovo elenco immutabile con l'argomento specificato come elemento aggiuntivo alla fine. Quindi, per creare un elenco di stringhe con valori "Hello", "immutable", "world" puoi scrivere:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(Questo è il codice C #, e sono molto interessato a un suggerimento C # se ritieni che la lingua sia importante. Non è fondamentalmente una domanda di lingua, ma gli idiomi della lingua possono essere importanti.)
L'importante è che gli elenchi esistenti non vengano modificati da Foo
, quindi empty.Count
restituirebbe comunque 0.
Un altro modo (più idiomatico) per arrivare al risultato finale sarebbe:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
La mia domanda è: qual è il nome migliore per Foo?
EDIT 3 : Come rivelerò più avanti, il nome del tipo potrebbe non essere effettivamente ImmutableList<T>
, il che rende chiara la posizione. Immagina invece che sia TestSuite
e che sia immutabile perché l'intero quadro di cui fa parte è immutabile ...
(Fine della modifica 3)
Opzioni che ho escogitato finora:
Add
: comune in .NET, ma implica la mutazione dell'elenco originaleCons
: Credo che questo sia il nome normale nei linguaggi funzionali, ma privo di significato per coloro che non hanno esperienza in tali linguaggiPlus
: il mio preferito finora, non implica mutazione per me . Apparentemente questo è usato anche in Haskell ma con aspettative leggermente diverse (un programmatore Haskell potrebbe aspettarsi di aggiungere due liste insieme invece di aggiungere un singolo valore all'altra lista).With
: coerente con alcune altre convenzioni immutabili, ma non ha abbastanza la stessa "aggiunta" ad esso IMO.And
: non molto descrittivo.- Sovraccarico dell'operatore per +: non mi piace molto; In genere penso che gli operatori dovrebbero essere applicati solo a tipi di livello inferiore. Sono disposto a essere persuaso però!
I criteri che sto usando per scegliere sono:
- Fornisce l'impressione corretta del risultato della chiamata al metodo (ovvero che è l'elenco originale con un elemento aggiuntivo)
- Rende il più chiaro possibile che non muta l'elenco esistente
- Sembra ragionevole quando incatenati insieme come nel secondo esempio sopra
Si prega di chiedere maggiori dettagli se non mi sto chiarendo abbastanza ...
EDIT 1: Ecco il mio ragionamento per preferire Plus
a Add
. Considera queste due righe di codice:
list.Add(foo);
list.Plus(foo);
Dal mio punto di vista (e questa è una cosa personale) quest'ultima è chiaramente buggy - è come scrivere "x + 5;" come una dichiarazione a sé stante. La prima riga sembra a posto, finché non ti ricordi che è immutabile. In effetti, il modo in cui l'operatore plus da solo non muta i suoi operandi è un altro motivo per cui Plus
è il mio preferito. Senza il leggero fastidio del sovraccarico dell'operatore, fornisce comunque le stesse connotazioni, che includono (per me) la non mutazione degli operandi (o metodo target in questo caso).
EDIT 2: motivi per non gradire Aggiungi.
Diverse risposte sono effettivamente: "Vai con Aggiungi. Ecco cosa DateTime
fa, e String
ha Replace
metodi ecc. Che non rendono evidente l'immutabilità." Sono d'accordo - qui c'è la precedenza. Tuttavia, ho visto un sacco di persone chiamano DateTime.Add
o String.Replace
e si aspettano la mutazione . Ci sono un sacco di domande sui newsgroup (e probabilmente SO se scavo in giro) a cui si risponde "Stai ignorando il valore di ritorno di String.Replace
; le stringhe sono immutabili, viene restituita una nuova stringa".
Ora, dovrei rivelare una sottigliezza alla domanda: il tipo potrebbe non essere in realtà un elenco immutabile, ma un tipo immutabile diverso. In particolare, sto lavorando a un framework di benchmarking in cui aggiungi test a una suite e che crea una nuova suite. Potrebbe essere ovvio che:
var list = new ImmutableList<string>();
list.Add("foo");
non realizzerà nulla, ma diventa molto più oscuro quando lo cambi in:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
Sembra che dovrebbe essere a posto. Considerando che questo, per me, rende più chiaro l'errore:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
Sta solo chiedendo di essere:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
Idealmente, vorrei che ai miei utenti non venisse detto che la suite di test è immutabile. Voglio che cadano nella fossa del successo. Questo potrebbe non essere possibile, ma mi piacerebbe provare.
Mi scuso per l'eccessiva semplificazione della domanda originale parlando solo di un tipo di elenco immutabile. Non tutte le raccolte sono auto-descrittive come ImmutableList<T>
:)