Tipos básicos (cont.)
Introducción
En la clase anterior comenzamos a explorar los tipos básicos que soporta Elixir. En esta clase vamos a continuar explorando otros tipos básicos, como funciones anonimas, listas y las tuplas. Comencemos.
Funciones anónimas
Elixir también provee funciones anónimas. Las funciones anónimas nos permiten guardar y pasar código ejecutable como si se tratara de un entero o flotante. Están delimitadas por las palabras clave fn
y end
.
add = fn a, b -> a + b end
add.(1, 2)
is_function(add)
En el ejemplo anterior, definimos una función anónima que recibe dos argumentos, a
y b
, y retorna el resultado de a + b
. Los argumentos siempre están en el lado izquierdo de ->
y el código que será ejecutado se encuentra en el lado derecho. La función anónima es guardada en la variable add
.
Podemos invocar la función anónima pasándole argumentos. Nota el punto (.
) alrededor de la variable y los paréntesis son requeridos para invocar la función anónima. El punto asegura que no hay ambiguedad entre llamar a una función anónima que coincide con la variable add
y la función que lleva por nombre add/2
. Más adelante veremos como definir nuestras propias funciones con nombres. Por ahora, recuerda que Elixir hace una clara distinción entre funciones anónimas y funciones que llevan nombres.
Las funciones anónimas en Elixir también son identificadas por el número de argumentos que reciben. Podemos verificar si una función recibe cierta cantidad de argumentos usando is_function/2
.
is_function(add, 2)
is_function(add, 1)
Finalmente, las funciones anónimas pueden acceder a variables que estén al alcance de la función cuando fue definida. Esto es tipicamente conocido como clausuras. Definamos una nueva función anónima que usa a add
, que hemos definido previamente también como función anónima:
double = fn a -> add.(a, a) end
double.(2)
Es importante aclarar que una variable asignada dentro de una función anónima no afecta el entorno que la rodea.
x = 42
(fn -> x = 0 end).()
x
Listas
Elixir usa corchetes para especificar una lista de valores. Los valores pueden ser de cualquier tipo:
[1, 2, true, 3]
length([1, 2, 3])
Dos listas pueden ser concatenadas or substraidas usando los operadores ++/2
y --/2
respectivamente:
[1, 2, 3] ++ [4, 5, 6]
[1, true, 2, false, 3, true] -- [true, false]
Los operadores sobre listas nunca modifican la lista existente. Concatenar o remover elementos de una lista retorna una nueva lista. Por lo tanto, decimos que las estructuras de datos en Elixir son inmutables. Una ventaja de la inmutabilidad es que tiende a código más limpio. Eres libre de pasar datos entre llamadas con la garantía que ninguna mutará el dato original en memoria, solo lo transformará en otros datos.
Usualmente cuando hablamos de listas, nos interesa acceder a la cabeza de la lista y su cola. La cabeza es el primer elemento de la lista y su cola es lo remanente de la lista. Podemos acceder a ellas con las funciones hd/1
y tl/2
. Asignemos una lista a una variable y obtengamos su cabeza y cola.
list = [1, 2, 3]
hd(list)
tl(list)
Si tratamos de obtener la cabeza o la cola de una lista vacía obtenemos un error.
hd([])
tl([])
Tuplas
Elixir usa llaves para definir tuplas. Como las listas, las tuplas pueden contener cualquier tipo de dato.
{:ok, "hello"}
tuple_size({:ok, "hello"})
Las tuplas almacenan elementos de manera contigua en memoria. Esto quiere decir que acceder a un elemento de la tupla por su índice u obtener el tamaño de la tupla es una operación muy rápida. El índice comienza a partir de cero.
tuple = {:ok, "hello"}
elem(tuple, 1)
tuple_size(tuple)
También es posible poner un elemento en un índice particular de la tupla con put_elem/3
tuple = {:ok, "hello"}
put_elem(tuple, 1, "world")
tuple
Nota que put_elem/3
retornó una nueva tupla. La tupla original almacenada en la variable tuple
no fue modificada. Así como con las listas, las tuplas son inmutables. Cada operación que modifica una tupla, retorna una nueva tupla, nunca cambiará la tupla dada como argumento.
Retos
- Utiliza funciones anónimas para definir un conversor entre distintas monedas. O si lo prefieres, puedes hacer un conversor de temperatura.
- Vimos que podíamos concatenar y substraer listas, ¿crees que podamos hacer lo mismo con las tuplas?, déjame en el sistema de comentarios como podrías hacerlo.
-
Utiliza la función de ayuda
h
y lee la documentación de las funciones comentadas en esta clase.
Agradecimientos
Este tutorial es una traduccion libre del contenido presentado en la seccion Basic Types, el cual es parte de la guia oficial de Elixir.