- John Carmack compartilhou sua visão pessoal sobre o uso de variáveis mutáveis (mutable variables)
- Mencionou que, ao usar Python, acabou relaxando o princípio de “atribuição única” (single assignment), e que precisa se policiar quanto a isso
- Enfatizou que, exceto pelos cálculos iterativos em loops, deve-se evitar reatribuir ou atualizar variáveis
- Se todas as etapas intermediárias de cálculo forem mantidas, isso ajuda na depuração e evita problemas em que um valor anterior é usado sem querer ao mover blocos de código
- Explicou que, em C/C++, é um bom hábito declarar quase todas as variáveis como
const no momento da inicialização
- Por fim, destacou que “gostaria que
mutable fosse uma palavra-chave”, expressando o desejo de que a imutabilidade fosse o padrão
1 comentários
Comentários do Hacker News
Depois de usar Clojure por 2 anos, percebi como é realmente difícil explicar para outros desenvolvedores a clareza que a imutabilidade traz
Quem está acostumado a pensar em termos de produzir efeitos por meio de mudanças de estado tem dificuldade de entender isso antes de experimentar na prática
Por exemplo, se você escreve
x = 7; x = x + 3; x = x / 2, trocar a ordem não gera erro, mas muda o resultadoJá quando se usam novas variáveis como
x1,x2, uma ordem incorreta causa erro e deixa o problema evidenteNo fim, atribuição única (single assignment) é uma forma de expressar explicitamente essa dependência
Mesmo explicando a colegas que nunca tinham usado uma linguagem funcional o quanto um modo de pensar centrado em funções é fácil de testar e limpo, isso não fazia muito sentido para eles
Em Python é difícil escrever em estilo funcional de um jeito agradável de ler, e JS parece melhor nisso
No fim, só desenvolvedores curiosos acabam tentando linguagens como Clojure
A função não precisa conhecer o estado externo, e o exterior também não precisa conhecer o interior da função
Mesmo sem conhecer o estado total do programa, dá para testar ou depurar uma função específica de forma isolada
É interessante ver a comunidade Haskell acabar tentando reinventar mutabilidade dentro do sistema de tipos
O ponto central é controlar os efeitos colaterais com o menor custo possível
Haskell tinha uma barreira de entrada alta por causa do sistema de tipos, e F# era conciliador demais, então eu acabava programando com sintaxe de C#
Graças à homoiconicity de Clojure e às suas estruturas de dados poderosas, a ideia de “trabalhar com valores” finalmente ficou clara para mim
Eu não usaria profissionalmente, mas com certeza recomendaria para quem nunca teve experiência com linguagem funcional ou Lisp
Eu gostaria que as variáveis fossem imutáveis por padrão e que tudo fosse expressão (expression)
Mas a realidade é que, como desenvolvedor de Clojure, estou sofrendo com a invasão do Python
Agora estou sofrendo com a invasão do TypeScript, então entendo bem
Essa abordagem é realmente útil para limitar o escopo das mudanças
Não há necessidade de entrar em guerras tribais entre linguagens
Na era do aumento de produtividade, essas fronteiras não fazem sentido
Recomendo o texto Don’t Call Yourself a Programmer
Tento minimizar a reatribuição de variáveis, mas às vezes uso shadowing de variáveis
Gosto de padrões como
result = result.process()por serem concisosPor exemplo, se
process()for uma função de validação, pode ficar ambíguo em que momento aquele valor foi processadoPor isso, é melhor distinguir claramente os estados pelos nomes
Ex.:
result = x |> foo |> bar |> bazou(-> x foo bar baz)result.process()? Mas afinal, que result e que process são esses?”Quem ler esse código depois vai ficar confuso
O próprio termo “variável (variable)” sempre me incomoda
Se é imutável, por que chamar de variável?
Em Rust, ela só pode ser alterada se isso for explicitado com
mutJá em C, para criar uma constante é preciso usar o pré-processador, o que é confuso
xde uma função recebe valores diferentes a cada chamada, então ele mesmo é um valor que variaMesmo sem reatribuição, ainda pode ser chamado de variável
A programação herdou esse conceito diretamente
Uma constante (constant) tem o mesmo valor em todas as execuções
Veja Variable (mathematics)
Seria ótimo se a IDE mostrasse visualmente se uma variável foi alterada
Por exemplo, destacando levemente as variáveis modificadas
Usar
finalsempre que possível torna o código mais fácil de ler e manterA IDE deveria avisar, e a alteração só ser permitida quando realmente necessária
Como na discussão do Rich Hickey sobre set vs list, é preciso escolher estruturas que expressem claramente o significado
Já participei de um projeto em que a imutabilidade foi aplicada de forma rigorosa por causa da segurança de threads
Isso deixou o código mais fácil de ler e tornou mais simples rastrear o que pode mudar
Desde então virei um grande fã de imutabilidade
Depois de trabalhar em uma grande base de código em Haskell e voltar para C, fiquei pensando como seria bom se imutabilidade fosse o padrão
constnão é suficientePara mutar é preciso usar ponteiros, e em C++ até uma chamada de função pode alterar argumentos, o que fica opaco
Concordo com a ideia de que “quase todas as variáveis deveriam ser declaradas como const”
Faz sentido mencionar Rust aqui
Imagino uma sintaxe em que o padrão seja imutável, e mutable só seja permitido dentro de um bloco específico
Por exemplo, como um bloco
withem PythonAo sair do bloco, tudo voltaria a ser imutável
Basta olhar o borrow checker do Rust para ver como esse conceito é complexo
Existe a frase “State is the enemy”
Quanto mais estado existe, mais as condições a testar crescem exponencialmente
A imutabilidade é uma forma de evitar essa explosão de estados
Separation of Church and State