Perdón por el título waffly: si pudiera encontrar un título conciso, no tendría que hacer la pregunta.
Supongamos que tengo un tipo de lista inmutable. Tiene una operación Foo(x)
que devuelve una nueva lista inmutable con el argumento especificado como un elemento adicional al final. Entonces, para crear una lista de cadenas con los valores "Hola", "inmutable", "mundo", podría escribir:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(Este es el código C #, y estoy más interesado en una sugerencia C # si considera que el idioma es importante. No es fundamentalmente una pregunta de idioma, pero los modismos del idioma pueden ser importantes).
Lo importante es que las listas existentes no se alteran, por Foo
lo empty.Count
que aún devolvería 0.
Otra forma (más idiomática) de llegar al resultado final sería:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
Mi pregunta es: ¿cuál es el mejor nombre para Foo?
EDITAR 3 : Como revelaré más adelante, el nombre del tipo podría no serlo ImmutableList<T>
, lo que aclara la posición. Imagine en cambio que es TestSuite
y que es inmutable porque todo el marco del que forma parte es inmutable ...
(Fin de la edición 3)
Opciones que se me han ocurrido hasta ahora:
Add
: común en .NET, pero implica la mutación de la lista originalCons
: Creo que este es el nombre normal en lenguajes funcionales, pero no tiene sentido para aquellos sin experiencia en dichos lenguajesPlus
: mi favorito hasta ahora, no implica mutación para mí . Aparentemente, esto también se usa en Haskell, pero con expectativas ligeramente diferentes (un programador de Haskell podría esperar que agregue dos listas juntas en lugar de agregar un solo valor a la otra lista).With
: consistente con algunas otras convenciones inmutables, pero no tiene la misma "incorporación" a la OMI.And
: no muy descriptivo.- Sobrecarga del operador para +: Realmente no me gusta tanto; En general, creo que los operadores solo deberían aplicarse a los tipos de nivel inferior. ¡Aunque estoy dispuesto a ser persuadido!
Los criterios que estoy usando para elegir son:
- Da la impresión correcta del resultado de la llamada al método (es decir, que es la lista original con un elemento adicional)
- Deja lo más claro posible que no muta la lista existente
- Suena razonable cuando se encadenan juntos como en el segundo ejemplo anterior
Solicite más detalles si no me estoy aclarando lo suficiente ...
EDIT 1: Aquí está mi razonamiento para preferir Plus
a Add
. Considere estas dos líneas de código:
list.Add(foo);
list.Plus(foo);
Desde mi punto de vista (y esto es algo personal), este último tiene errores, es como escribir "x + 5"; como una declaración por sí sola. Parece que la primera línea está bien, hasta que recuerdes que es inmutable. De hecho, la forma en que el operador plus por sí solo no muta sus operandos es otra razón por la cual Plus
es mi favorito. Sin la ligera aspereza de la sobrecarga del operador, todavía da las mismas connotaciones, que incluyen (para mí) no mutar los operandos (o el objetivo del método en este caso).
EDIT 2: Razones para no gustar Agregar.
Varias respuestas son efectivas: "Vaya con Agregar. Eso es lo que DateTime
hace, y String
tiene Replace
métodos, etc. que no hacen obvia la inmutabilidad". Estoy de acuerdo, hay prioridad aquí. Sin embargo, he visto un montón de personas que llaman DateTime.Add
o String.Replace
y esperan que la mutación . Hay un montón de preguntas de grupos de noticias (y probablemente SO si cavo) que son respondidas por "Estás ignorando el valor de retorno de String.Replace
; las cadenas son inmutables, se devuelve una nueva cadena".
Ahora, debo revelar una sutileza a la pregunta: el tipo podría no ser realmente una lista inmutable, sino un tipo inmutable diferente. En particular, estoy trabajando en un marco de evaluación comparativa en el que agrega pruebas a una suite, y eso crea una nueva suite. Puede ser obvio que:
var list = new ImmutableList<string>();
list.Add("foo");
no va a lograr nada, pero se vuelve mucho más oscuro cuando lo cambia a:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
Parece que debería estar bien. Mientras que esto, para mí, aclara el error:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
Eso es solo rogar ser:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
Idealmente, me gustaría que mis usuarios no tengan que decirles que el conjunto de pruebas es inmutable. Quiero que caigan en el pozo del éxito. Puede que esto no sea posible, pero me gustaría intentarlo.
Pido disculpas por simplificar demasiado la pregunta original al hablar solo de un tipo de lista inmutable. No todas las colecciones son tan autodescriptivas como ImmutableList<T>
:)