Road to Elm - Table of Contents
Destructuring is a handy tool, available in many functional languages (also in Javascript ES6).
It's a more succinct syntax to extract single values from collections of various types.
Extracting values from objects or arrays and assigning them to local variables is one of the little things you do in programming without even thinking about it.
There's not much of a choice: littering your code with object.property.property.property or array[0] is longer to write, has slower performance, and is untidy.
Less code
In pre-ES6 Javascript that was a line by line affair:
var r1 = [9, 8];  
function area (rect){  
  var w = rect[0];
  var h = rect[1];
  return w * h;
}
In Elm, it would look like this:
r1 = (9, 8)
addAreas : (Int, Int) -> Int  
area rect =  
  let
    (w, h) = rect -- using destructuring
  in 
    w * h
So we exchange two lines:
var w = rect[0];
var h = rect[1];
for one
(w, h) = rect
and we end up with the same result, w is 9, and h is 8.
If we had something longer, like:
var list = [2, 5, 6, 7, 8];
var x = list[0];
var y = list[1];
var z = list[2];
var a = list[3];
var b = list[4];
it would still be one line in Elm:
list = (2,5,6,7,8)
(x, y, z, a, b) = list
Skipping
or maybe you want only x, a, and b:
list = (2,5,6,7,8)
(x, _, _, a, b) = list
_ will be ignored.
Objects/Records example
So we looked at tuples (Elm) and arrays (Javascript), now let's do the same for records (Elm) and objects (Javascript).
Objects and records are not the same, but they are similar enough for our purposes in this article, much like tuples and arrays.
var r1 = { x : 9, y : 8 };  
function area (rect) {  
  var w = rect.x;
  var h = rect.y;
  return w * h;
}
the same in Elm:
type alias Rect
  = { x : Int
    , y : Int
    }
area : Rect -> Int  
area rect =  
  let
    { x, y } = rect -- using destructuring
  in 
    x * y
you can also use it in place of the argument name:
area : Rect -> Int  
area { x, y } =  
  x * y
this way you skipped even the let, but notice that it was necessary to use x and y, matching the Rect type definition, instead of being able to use different letters, as w and h in the let above.
Some fancier examples
Nested destructuring
You can also extract values from a tuple inside a tuple:
tryNested ( x,( w, h ), g ) =
  w
> tryNested (5, (6,7), 3)
6 : number
or a record inside a tuple:
tryNested ( x, { w, h }, g ) =
   w
> tryNested ( 3, { w=3, h=5 }, 6)
3 : number
Use within case
You can destructure a record from the arguments and then use it in a case...of within a tuple:
tryCase { x, y } =
  case (x, y) of
    (5,5) -> "Correct"
    (_,3) -> "Less correct"
    _ -> "Wrong"
which we can try out in elm-repl:
> tryCase {x = 5, y = 7}
"Wrong" : String
> tryCase {x = 5, y = 5}
"Correct" : String
> tryCase {x = 4, y = 3}
"Less correct" : String
Reminder
In a function always assign your variables within a let!
Comments? Give me a shout at @lambda_cat. 
To get the latest post updates subscribe to the LambdaCat newsletter. 
You can support my writing on LambdaCat's Patreon.
