A equipe do Java fez um grande trabalho removendo barreiras à programação funcional no Java 8. Em particular, as alterações nas coleções java.util fazem um ótimo trabalho de encadear transformações em operações de fluxo muito rápido. Considerando o bom trabalho que fizeram ao adicionar funções de primeira classe e métodos funcionais nas coleções, por que eles falharam completamente ao fornecer coleções imutáveis ou até mesmo interfaces de coleção imutáveis?
Sem alterar nenhum código existente, a equipe Java pode, a qualquer momento, adicionar interfaces imutáveis iguais às mutáveis, menos os métodos "set" e fazer com que as interfaces existentes se estendam a partir deles, assim:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Claro, operações como List.add () e Map.put () atualmente retornam um valor booleano ou anterior para a chave especificada para indicar se a operação foi bem-sucedida ou falhou. Coleções imutáveis teriam que tratar métodos como fábricas e retornar uma nova coleção contendo o elemento adicionado - que é incompatível com a assinatura atual. Mas isso pode ser contornado usando um nome de método diferente, como ImmutableList.append () ou .addAt () e ImmutableMap.putEntry (). A verbosidade resultante seria mais do que compensada pelos benefícios de trabalhar com coleções imutáveis, e o sistema de tipos impediria erros de chamar o método errado. Com o tempo, os métodos antigos podem ser preteridos.
Vitórias de coleções imutáveis:
- Simplicidade - o raciocínio sobre o código é mais simples quando os dados subjacentes não são alterados.
- Documentação - se um método usa uma interface de coleção imutável, você sabe que não vai modificar essa coleção. Se um método retorna uma coleção imutável, você sabe que não pode modificá-lo.
- Simultaneidade - coleções imutáveis podem ser compartilhadas com segurança entre threads.
Como alguém que experimentou idiomas que assumem imutabilidade, é muito difícil voltar ao oeste selvagem de uma mutação desenfreada. As coleções de Clojure (abstração de sequência) já possuem tudo o que as coleções do Java 8 fornecem, além de imutabilidade (embora talvez usando memória e tempo extras devido a listas vinculadas sincronizadas em vez de fluxos). O Scala tem coleções mutáveis e imutáveis com um conjunto completo de operações e, embora essas operações sejam ágeis, chamar o .iterator oferece uma visão lenta (e existem outras maneiras de avaliá-las). Não vejo como o Java pode continuar competindo sem coleções imutáveis.
Alguém pode me apontar para a história ou discussão sobre isso? Certamente é público em algum lugar.
const
coleções
Collections.unmodifiable*()
. mas não os trate como imutáveis quando não são
ImmutableList
nesse diagrama, as pessoas podem passar um mutável List
? Não, isso é uma violação muito ruim do LSP.