8. Variables
En algún momento deberemos guardar valores para reutilizarlos de forma recurrente con un alias fácil de recordar. O dicho de otro modo, habrá que crear variables.
La función para declarar una variable, recuerda que todo son funciones, se denomina def o let. El primer argumento será el alias y el segundo el valor.
(def dama "Dulcinea del Toboso") ; La variable se denomina "dama" y contiene "Dulcinea del Toboso"
En el ejemplo se ha introducido un String, aunque disponemos de un amplio surtido de tipos.
42 ; Entero
-1.5 ; Float o coma flotante (decimales)
22/7 ; Proporción
"hello" ; String (cadena de caracteres)
\a ; Carácter
#"[0-9]+" ; Expresión regular
true false ; Booleanos
:key ; key o llave
nil ; Nulo
def es una variable global, por lo que puede ser accesible desde cualquier parte del namespace (espacio de trabajo).
Las variables locales contienen una estructura diferente.
(let [burro "Rucio"] "todo el código que hace uso de la variable")
Si necesito varias variables locales las estructuraría dentro de [].
(let [variable "contenido"
variable2 "contenido"
variable3 "contenido"] "todo el código que hace uso de la variable")
En el siguiente ejemplo declaro 2 números, de tipo entero, y los sumo entre sí para acto seguido mostrarlo por pantalla.
(let [num1 10
num2 5] (println (+ num1 num2)))
; 15
Pero si intentara acceder a num1 desde fuera no será posible.
(let [num1 10
num2 5] (println (+ num1 num2)))
; 15
(print num1)
; Unable to resolve symbol: num1 in this context
Nos alerta de que no existe, al menos en el espacio donde estamos trabajando. Nos evita colisiones con otras variables de otras lógicas o funciones. Intenta que sea tu primera elección.
Ya hemos visto cómo se crean y leen. Pero… ¿cómo modifico la variable? Al trabajar con un lenguaje con una base funcional, considera que todas las variables def y let son constantes. Se presupone que no vas a cambiar su contenido, que sus valores son inmutables. También es cierto que existe un tipo de variable especial llamada Atom que sí nos permitirá cambiar su valor, aunque se use en ocasiones muy limitadas.
Atoms
No solo de la inmutabilidad vive el programador. Hay casos concretos que debemos disponer de una estructura de datos mutable o un sencillo estado. Un uso común es la de memorizar alguna información que debe alterarse, como cálculos donde debamos guardar alguna información (tal vez al calcular la secuencia de Fibonacci) o una estructura (elementos dentro de un carrito de compra). A esta característica se le denomina Atom.
Para crear un Atom usaremos la función atom junto a la variable def. En el siguiente ejemplo creo un Atom con el alias mensaje-flash y el valor Identificado correctamente.
(def mensaje-flash (atom "Identificado correctamente"))
Para leer el valor, añadimos un arroba como prefijo.
(println @mensaje-flash)
; "Identificado correctamente"
Si deseamos modificar el valor usaremos reset!.
(reset! mensaje-flash "Sesión cerrada")
; "Sesión cerrada"
Otra posibilidad interesante es swap! donde en lugar de dar un valor le damos una función.
(def mensaje-flash (atom "Verifica E-Mail"))
; "Verifica E-Mail"
(swap! mensaje-flash clojure.string/upper-case)
; "VERIFICA E-MAIL"
Imprimir
Hasta ahora te has encontrado que se ha hecho uso de println para mostrar cierto contenido por el terminal. No es la única forma.
print: en línea.
(print "cura")
; "cura"nil
(print "cura" "ventero" "sabio")
; "cura" "ventero" "sabio"nil
-
pr: comoprint, pero produce salida legible por Clojure (preserva comillas y caracteres de escape). -
println: en una nueva línea.
(println "cura")
; cura
; nil
prn: comoprintln, pero produce salida legible por Clojure.
Veamos en acción ambas, un print con y sin salto de línea.
En el siguiente ejemplo estoy iterando una lista con 3 personajes y los estoy imprimiendo con print.
(doseq [profesion (list "cura" "ventero" "sabio")]
(pr profesion))
; curaventerosabionil
Ahora, en cambio, uso println.
(doseq [profesion (list "cura" "ventero" "sabio")]
(prn profesion))
; cura
; ventero
; sabio
; nil
Resumen
-
defse usa para crear variables globales dentro del espacio de trabajo. -
letse usa para crear variables locales, recomendado con funciones. -
atomse usa para crear variables mutables, raro su uso. -
Podemos imprimir en la misma línea o en una nueva con
printoprintln. -
print/printlnimprimen para humanos (sin comillas en strings). -
pr/prnimprimen en formato legible por Clojure (con comillas, escapando caracteres).
Ejercicios
-
Crea una variable con tu nombre y otra con tu edad. Imprime ambos valores en la misma línea.
-
Vamos a imaginar que existe la criptomoneda de Clojure: Cloin. Crea una variable llamada
carteracon el valor340. Crea otra variable llamadacartera-con-impuesto, donde su valor seacarteracon un incremento de un 21%. Imprime ambas carteras por pantalla. -
Crea un
Atomllamadocloins, con el valor inicial 0. Modifícalo para añadir 50. Por último incrementa su valor en 1.
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Support me on Ko-fi