I'm not familiar with this term "destructuring." Can you elaborate on the concept? Might you have an example of a destructure operation and a language where its's used?
I'm not familiar with this term "destructuring." Can you elaborate on the concept? Might you have an example of a destructure operation and a language where its's used?
Basically it means that you can assign several variables at once, by asssigning a complex value to an aproprietly structured literal with variables as placeholders.
In pseudojavascript, let's say you got this from some API:
var someList = [1, 2, 3, 4];
var someMap = { name: "John Smith",
age: 20,
cars: [{ id: "AAA-1111", model: "Ford T"},
{ id: "AAA-1112", model: "Mercedes Benz"}] }
And you want to extract useful data for your code quickly. In languages with destructuring you can do sth like this: var [x, y & rest] = someList; //x==1, y==2, rest == [3, 4]
var { "name": name,
"age": age,
"cars": [ {"id": firstCarId, "model": firstCarModel}
& restOfTheCars ]
} = someMap;
And the language will put the correct values in your variables name, age, firstCarId, firstCarModl, restOfTheCars. > let a = [1,2,3]
undefined
> [x,y,z] = a
Array(3) [ 1, 2, 3 ]
> x
1
> y
2
> z
3In nearly every other language, when you call a function, the top of the function typically involves a fair bit of analysis of the arguments to decide what needs to be done.
(That's being generous: typically the entire body of the function revolves around making decisions about what to do, such that you don't know what's going to come out of the function until you've traversed multiple branch options.)
In well-written Erlang, the function itself branches at the top, taking advantage of pattern matching, destructuring, and function heads.
Let's say you're passing around arbitrary data in the form of a tuple that you need to display. Or not, depending on the value of some debug flag.
In Python you might see code like this, assuming that an integer is stored in your program like ('int', 3) and a string might have some arbitrary label, so it's ('str', 'label', 'real string'):
if (debug):
display(x)
def display(x):
if (x[0] == 'int'):
display_int(x[1])
elif (x[0] == 'str'):
display_string(x[1], x[2])
In Erlang, you can branch and destructure at the function head. You don't check the debug flag in the calling code, just pass it along for the function to decide what to do with it; if the flag is false, the function just returns false. (Variables in Erlang are capitalized; the lower-case "strings" in this code are atoms, also called symbols in some languages.) display(_, false) ->
false;
display({int, N}, _) ->
display_int(N);
display({str, Label, String}, _) ->
display_string(Label, String).
Since you can choose the key data elements in your function arguments and branch accordingly in the function head, it becomes immediately obvious looking at the code how many different ways the code can evaluate, and the destructuring in the function heads means you don't have to waste code chunking the data apart before working with it.(Updated: forgot to include the debug flag in the 2nd and 3rd function heads. In all 3 heads, the _ pseudo-variable basically says "I don't care what value we have here". Another option would be to use _Debug in the 2nd and 3rd heads to indicate to the reader what the flag is, or use true since we're expecting that value.)
> let {a,b} = {a: 1, b: 2}
> a
1
> b
2