Destructuración🔗
No creo que sea reconocida como valida la palabra destructuración sin embargo es la traducción que se puede encontrar de destructuring. Igual y uno podría usar desempaquetado.
Destructuring se entiende como una manera concisa de dar nombres a valores encontrados en una colección, que en términos de programación sería variables y estructuras de datos.
Ahora bien, el tema gira alrededor de parallel assignment, por lo que también se podría hablar de simultaneous assignment, multiple assignment y unpacking.
Variables🔗
Todo un tema… ¿estoy hablando de asociación (binding) o de asignación?… ¿estoy dando nombre a un valor o a una ubicación de memoria?… ¿es destructiva o de ocultación?.
Estructuras de datos🔗
Al menos solemos trabajar con dos tipos de estructuras de datos:
- Secuenciales: listas y arreglos, por ejemplo.
- Asociativas: mapas y conjuntos, por ejemplo.
Una vez más… ¿estoy hablando de una estructura de datos como valor o como un espacio de memoria?… ¿es una estructura de datos estática o dinámica?… ¿los datos en ella son de tipo mixto u homogéneo?.
Por cierto, ¿las cadenas de caracteres (string) son estructuras de datos?… ¿el lenguaje de programación me permite trabajar con ellas como si lo fueran?.
Métodos y/o funciones🔗
Y finalmente… ¿estoy hablando de paso por valor o paso por referencia?… ¿estoy trabajando con una variable local o una variable global… en fin.
Ejemplos🔗
Algunos ejemplos de destructuración que podemos encontrar en lenguajes de programación:
Clojure🔗
Cuenta con una sintaxis que refleja la estructura de datos a destructurar:
-
En secuencias: se asocia
a
,b
yc
a los valores encontrados en el vector[10 20 30]
, evaluando[c b a]
.=> (let [[a b c] [10 20 30]] (vector c b a)) ;; [30 20 10]
-
En asociaciones: se asocia
a
al valor de la llave:x
,b
al valor de la llave:y
yc
al valor de la llave:z
encontrados en el mapa{:x 10 :y 20 :z 30}
, evaluando[c b a]
.=> (let [{a :x b :y c :z} {:x 10 :y 20 :z 30}] (vector c b a)) ;; [30 20 10]
-
En funciones:
=> (defn f [[a b c]] [c b a]) => (f [10 20 30]) ;; [30 20 10] => (defn g [{a :x b :y c :z}] [c b a]) => (g {:x 10 :y 20 :z 30}) ;; [30 20 10] => (defn h [x] [(dec x) x (inc x)]) => (let [[a b c] (h 10)] [c b a]) ;; [11 10 9] => (map (fn [[a b c]] [c b a]) [[10 20 30] [40 50 60] [70 80 90]]) ;; ([30 20 10] [60 50 40] [90 80 70])
-
En cadenas de caracteres:
=> (let [[a b c] "HOLA"] [c b a]) ;; [\L \O \H]
Ruby🔗
Cuenta con dos sintaxis: una mediante la asignación en paralelo y otra mediante el splat operator (*
):
-
En secuencias: se asocia
a
,b
yc
a los valores encontrados en el arreglo[10 20 30]
, evaluando[c b a]
> a, b, c = [10, 20, 30] > [c, b, a] # [30, 20, 10]
-
En asociaciones: se asocia
a
al valor de la llave:x
,b
al valor de la llave:y
yc
al valor de la llave:z
encontrados en el hash{:x 10 :y 20 :z 30}
, evaluando[c b a]
.> a, b, c = {x: 10, y: 20, z: 30}.values_at(:x, :y, :z) > [c, b, a] # [30, 20, 10]
-
En funciones:
> def f(a, b, c) [c, b, a] end > f(*[10, 20, 30]) # [30, 20, 10] > def g(a, b, c) [c, b, a] end > g(*{x: 10, y: 20, z: 30}.values_at(:x, :y, :z)) # [30, 20, 10] > def h(x) [x.pred, x, x.next] end a, b, c = h(10) > [c, b, a] ;; [11, 10, 9] > [[10, 20, 30], [40, 50, 60], [70, 80, 90]].map {|a, b, c| [c, b, a]} # [[30, 20, 10], [60, 50, 40], [90, 80, 70]]
-
En cadenas de caracteres:
> a, b, c = "HOLA".chars > [c, b, a] # ["L", "O", "H"]
En conclusión🔗
El tema de destructuring varia entre los lenguaje de programación debido a la semántica, de ahí que uno se cuestione sobre el concepto que se tenga de variable y estructura de datos. Algo común, considero, es ver a la destructuración como una forma idiomática, apoyada por la sintaxis en un lenguaje de programación, para acceder al contenido de una estructura de datos sin lidiar directamente con la organización o el recorrido de la misma. Lo anterior libera al programador de escribir las instrucciones singulares para cada operación de acceso a la información, pero sobre todo, permite que el código refleje la organización de la estructura de datos con la cual se trabajará.