Objetos imutáveis vs. coleções imutáveis
Um dos pontos mais delicados do debate sobre objetos mutáveis e imutáveis é a possibilidade de estender o conceito de imutabilidade às coleções. Um objeto imutável é um objeto que geralmente representa uma única estrutura lógica de dados (por exemplo, uma sequência imutável). Quando você tem uma referência a um objeto imutável, o conteúdo do objeto não muda.
Uma coleção imutável é uma coleção que nunca muda.
Quando executo uma operação em uma coleção mutável, altero a coleção no local, e todas as entidades que têm referências à coleção verão a alteração.
Quando executo uma operação em uma coleção imutável, uma referência é retornada para uma nova coleção que reflete a alteração. Todas as entidades que têm referências a versões anteriores da coleção não verão a alteração.
Implementações inteligentes não precisam necessariamente copiar (clonar) toda a coleção para fornecer essa imutabilidade. O exemplo mais simples é a pilha implementada como uma lista vinculada única e as operações push / pop. Você pode reutilizar todos os nós da coleção anterior na nova coleção, adicionando apenas um nó para o envio e clonando nenhum nó para o pop. A operação push_tail em uma lista isolada, por outro lado, não é tão simples ou eficiente.
Variáveis / referências imutáveis vs. mutáveis
Algumas linguagens funcionais adotam o conceito de imutabilidade para fazer referência a objetos, permitindo apenas uma única atribuição de referência.
- Em Erlang, isso é verdade para todas as "variáveis". Só posso atribuir objetos a uma referência uma vez. Se eu operasse em uma coleção, não seria possível reatribuir a nova coleção à referência antiga (nome da variável).
- O Scala também constrói isso na linguagem, com todas as referências sendo declaradas com var ou val , vals sendo apenas atribuição única e promovendo um estilo funcional, mas vários permitem uma estrutura de programa mais semelhante a C ou Java.
- A declaração var / val é necessária, enquanto muitos idiomas tradicionais usam modificadores opcionais, como final em java e const em C.
Facilidade de Desenvolvimento vs. Desempenho
Quase sempre o motivo para usar um objeto imutável é promover a programação livre de efeitos colaterais e o raciocínio simples sobre o código (especialmente em um ambiente paralelo / altamente concorrente). Você não precisa se preocupar com os dados subjacentes sendo alterados por outra entidade se o objeto for imutável.
A principal desvantagem é o desempenho. Aqui está uma descrição de um teste simples que fiz em Java, comparando alguns objetos imutáveis versus mutáveis em um problema de brinquedo.
Os problemas de desempenho são discutíveis em muitos aplicativos, mas não em todos, e é por isso que muitos pacotes numéricos grandes, como a classe Numpy Array no Python, permitem atualizações no local de matrizes grandes. Isso seria importante para áreas de aplicação que fazem uso de grandes operações matriciais e vetoriais. Esses grandes problemas paralelos a dados e intensivos em computação alcançam uma grande velocidade ao operar no local.
string
é imutável, pelo menos no .NET, e acho que em muitas outras linguagens modernas também.