El equipo de Java ha realizado un gran trabajo eliminando barreras para la programación funcional en Java 8. En particular, los cambios en las colecciones java.util hacen un gran trabajo encadenando transformaciones en operaciones de transmisión muy rápidas. Teniendo en cuenta lo bien que han hecho al agregar funciones de primera clase y métodos funcionales en colecciones, ¿por qué no han podido proporcionar colecciones inmutables o incluso interfaces de colección inmutables?
Sin cambiar ningún código existente, el equipo de Java podría en cualquier momento agregar interfaces inmutables que sean las mismas que las mutables, menos los métodos "establecidos" y hacer que las interfaces existentes se extiendan desde ellos, de esta manera:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Claro, operaciones como List.add () y Map.put () actualmente devuelven un valor booleano o anterior para la clave dada para indicar si la operación tuvo éxito o no. Las colecciones inmutables tendrían que tratar tales métodos como fábricas y devolver una nueva colección que contenga el elemento agregado, lo cual es incompatible con la firma actual. Pero eso podría solucionarse utilizando un nombre de método diferente como ImmutableList.append () o .addAt () e ImmutableMap.putEntry (). La verbosidad resultante sería más que compensada por los beneficios de trabajar con colecciones inmutables, y el sistema de tipos evitaría errores al llamar al método incorrecto. Con el tiempo, los viejos métodos podrían quedar en desuso.
Victorias de colecciones inmutables:
- Simplicidad: el razonamiento sobre el código es más simple cuando los datos subyacentes no cambian.
- Documentación: si un método toma una interfaz de colección inmutable, sabe que no va a modificar esa colección. Si un método devuelve una colección inmutable, sabe que no puede modificarla.
- Simultaneidad: las colecciones inmutables se pueden compartir de forma segura entre hilos.
Como alguien que ha probado idiomas que asumen la inmutabilidad, es muy difícil volver al Salvaje Oeste de la mutación desenfrenada. Las colecciones de Clojure (abstracción de secuencia) ya tienen todo lo que proporcionan las colecciones de Java 8, más la inmutabilidad (aunque tal vez usando memoria y tiempo adicionales debido a listas enlazadas sincronizadas en lugar de secuencias). Scala tiene colecciones mutables e inmutables con un conjunto completo de operaciones, y aunque esas operaciones están ansiosas, llamar a .iterator ofrece una visión perezosa (y hay otras formas de evaluarlas perezosamente). No veo cómo Java puede seguir compitiendo sin colecciones inmutables.
¿Alguien puede señalarme la historia o la discusión sobre esto? Seguramente es público en alguna parte.
const
colecciones
Collections.unmodifiable*()
. pero no los trates como inmutables cuando no lo son
ImmutableList
en ese diagrama, ¿las personas pueden pasar un mutable List
? No, esa es una violación muy grave de LSP.