- John Carmack compartió su opinión personal sobre el uso de variables mutables
- Mencionó que, al usar Python, ha tendido a descuidar el principio de
single assignment, y que debe cuidarse de eso él mismo
- Enfatizó que, salvo en los cálculos repetitivos de los bucles, se debe evitar reasignar o actualizar variables
- Si se conservan todos los pasos intermedios del cálculo, eso ayuda durante la depuración y puede evitar problemas en los que se use accidentalmente un valor anterior al mover bloques de código
- Explicó que, en C/C++, es una buena práctica declarar casi todas las variables como
const en el momento de su inicialización
- Finalmente, subrayó que "ojalá
mutable fuera una palabra clave", expresando su deseo de que la inmutabilidad sea el valor predeterminado
1 comentarios
Opinión en Hacker News
Después de usar Clojure durante 2 años, sentí que era realmente difícil explicarles a otros desarrolladores la claridad que aporta la inmutabilidad
A quienes están acostumbrados a pensar en términos de producir efectos mediante cambios de estado les cuesta entenderlo antes de experimentarlo directamente
Por ejemplo, si escribes
x = 7; x = x + 3; x = x / 2, cambiar el orden no produce un error, pero sí un resultado distintoEn cambio, si usas variables nuevas como
x1,x2, un orden incorrecto provoca un error y hace que el problema quede claroEn última instancia, la asignación única (single assignment) es una forma de expresar explícitamente esas dependencias
Aunque les explicaba a colegas que nunca habían usado un lenguaje funcional lo fácil de probar y limpio que es pensar en funciones, no terminaba de hacerles clic
En Python es difícil escribir un estilo funcional que sea agradable de leer, y JS me parece mejor en ese sentido
Al final, solo los desarrolladores curiosos terminan probando lenguajes como Clojure
La función no necesita conocer el estado externo, y el exterior tampoco necesita conocer el interior de la función
Incluso sin conocer el estado completo del programa, puedes probar o depurar una función específica de forma independiente
Es interesante ver que la comunidad de Haskell termina intentando reinventar la mutabilidad dentro del sistema de tipos
La clave es controlar los efectos secundarios con el menor costo posible
Haskell tenía una barrera de entrada alta por su sistema de tipos, y F# era demasiado de compromiso, así que uno terminaba programando con sintaxis de C#
Gracias a la homoiconicidad de Clojure y a sus potentes estructuras de datos, por primera vez entendí claramente el concepto de “trabajar con valores”
No lo usaría profesionalmente, pero sí se lo recomendaría sin dudar a cualquiera que no tenga experiencia con lenguajes funcionales o Lisp
Me gustaría que las variables fueran inmutables por defecto y que todo fuera una expresión (expression)
Pero la realidad es que, como desarrollador de Clojure, sufro la invasión de Python
Ahora estoy sufriendo la invasión de TypeScript, así que lo entiendo
Esta forma de trabajar es muy útil para limitar el alcance de los cambios
No hace falta quedar atrapado en las guerras tribales entre lenguajes
En una era de aumento de productividad, esas fronteras no significan mucho
Recomiendo el texto Don’t Call Yourself a Programmer
Intento minimizar la reasignación de variables, pero a veces uso sombreado de variables
Prefiero patrones como
result = result.process()porque son concisosPor ejemplo, si
process()es una función de validación, puede volverse ambiguo en qué momento fue procesado ese valorPor eso es mejor distinguir claramente el estado mediante el nombre
Ejemplo:
result = x |> foo |> bar |> bazo(-> x foo bar baz)result.process()? ¿Qué result y qué process se supone que es eso?”Quien lea el código después va a confundirse
El término “variable” en sí siempre me ha hecho ruido
Si es inmutable, ¿por qué llamarla variable?
En Rust solo puede modificarse si se marca explícitamente con
mutEn cambio, en C hay que usar el preprocesador para crear constantes, lo cual resulta confuso
xde una función recibe un valor distinto en cada llamada, así que en sí mismo es un valor que varíaIncluso sin reasignación, puede seguir llamándose variable
La programación tomó ese concepto tal cual
Una constante (constant) tiene el mismo valor en todas las ejecuciones
Véase Variable (mathematics)
Estaría bien que el IDE mostrara visualmente si una variable fue modificada
Por ejemplo, que las variables modificadas tuvieran una pequeña marca
Usar
finaltanto como sea posible hace que el código sea más fácil de leer y mantenerEl IDE debería advertirlo y permitir cambios solo cuando de verdad sean necesarios
Como en la historia de set vs list de Rich Hickey, conviene elegir estructuras que expresen el significado con claridad
Antes trabajé en un proyecto donde se aplicó la inmutabilidad de forma estricta por seguridad de hilos
Gracias a eso, el código se volvió más fácil de leer y de seguir en cuanto a qué podía cambiar y qué no
Desde entonces soy un gran fan de la inmutabilidad
Después de trabajar en una gran base de código de Haskell y volver a C, me quedó la sensación de que la inmutabilidad debería ser el valor por defecto
constno alcanzaPara modificar necesitas usar punteros, y en C++ una llamada a función puede cambiar argumentos, lo que vuelve todo menos transparente
Coincido con la idea de que “conviene declarar casi todas las variables como const”
Vale la pena mencionar Rust
Imagino una sintaxis donde lo inmutable sea el valor por defecto y solo se permita mutable dentro de un bloque específico
Por ejemplo, como un bloque
withde PythonAl salir del bloque, volvería a ser inmutable
Basta ver el borrow checker de Rust para darse cuenta de lo complejo que es ese concepto
Hay una frase: “State is the enemy”
Mientras más estado haya, más crecen exponencialmente las condiciones que hay que probar
La inmutabilidad es una forma de evitar esa explosión de estado
Separation of Church and State