13

I need to know a correct name for this cool feature that some languages provide.

FYI: In some languages it is possible to do a multiple assignments by assigning a structure of values to a structure of "variables". In the example in the question title it assigns "foo" to foo and "bar" to bar.

tillda
  • 18,150
  • 16
  • 51
  • 70
  • Cool feature? Really? Never heard about that before but I find it only confusing. Soon we'll need some tools to make code "programmer readable". – Damien Oct 17 '10 at 03:56
  • 8
    @Damien: Wow, way to overreact. – Jorge Israel Peña Oct 17 '10 at 03:59
  • 8
    @Damien: [blub](http://www.paulgraham.com/avg.html) much? – Mark Rushakoff Oct 17 '10 at 04:09
  • 2
    Ok, sorry guys I definitely overreacted. But finally I'm glad I did because I got quite an interesting reading from you Mark. Thanks. And I promise I'll remove my java glasses next time. Those who have never been wrong can throw the first stone ;o) – Damien Oct 17 '10 at 23:54

8 Answers8

23

It's generally called destructuring bind in functional languages (which don't have assignments) and destructuring assignment in imperative languages.

Some languages provide subsets of that feature and then call it something different. For example, in Python it works with Tuples, Lists or Sequences and is called Tuple unpacking, List unpacking or Sequence unpacking, in Ruby, it works with Arrays (or objects that are convertible to an array) and is called parallel assignment.

Destructuring bind can get arbitrarily complex. E.g. this (imaginary) bind

[Integer(a), b, 2, c] = some_array

would assign the first element of some_array to a, the second element to b and the fourth element to c, but only if the first element is an Integer, the third element is equal to 2 and the length is 4. So, this even incorporates some conditional logic.

Destructuring bind is a subset of more general pattern matching, which is a standard feature of functional languages like Haskell, ML, OCaml, F#, Erlang and Scala. The difference is that destructuring bind only lets you take apart a structure and bind its components to variables, whereas pattern matching also matches on values inside those structures and lets you make decisions and in particular lets you run arbitrary code in the context of the bindings. (You can see the above imaginary bind as half-way in between destructuring bind and pattern matching.)

Here's the classical example of a reverse function in an imaginary language, written using pattern matching:

def reverse(l: List): List {
  match l {
    when []              { return [] }
    when [first :: rest] { return (reverse(rest) :: first) }
  }
}
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • @Matthew Flaschen: Thanks. I added *Sequence Unpacking* and dropped the word "only" from the description. – Jörg W Mittag Oct 20 '10 at 11:33
  • I should have been more clear in both my answer (updated) and comment. Tuples and lists are particular kinds of sequence in Python, so tuple unpacking and list unpacking are just special cases of sequence unpacking. – Matthew Flaschen Oct 20 '10 at 11:40
6

In Python it is known as list or sequence unpacking: http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences

my_list = ["foo", "bar"]
foo, bar = my_list
Adam Vandenberg
  • 19,991
  • 9
  • 54
  • 56
4

It's called parallel assignment in Ruby and other languages.

Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
3

Perl and PHP call it list assignment

Perl:

my ($foo, $bar, $baz) = (1, 2, 3);

PHP:

list($foo, $bar, $baz) = array(1, 2, 3);
Brad Mace
  • 27,194
  • 17
  • 102
  • 148
2

Mozilla calls it destructuring assignment. In Python, it's sequence unpacking; tuple unpacking is a common special case.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
2

If you view the right hand side as a tuple, one could view the assignment as a kind of Tuple Unpacking.

Ani
  • 111,048
  • 26
  • 262
  • 307
2

In Erlang it's ... well, it's not assignment, it's pattern matching (seeing as there is no assignment, as such, in Erlang).

$ erl
Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]

Eshell V5.8.1  (abort with ^G)
1> [H1, H2, H3| Rest] = [1,2,3,4,5].
[1,2,3,4,5]
2> H1.
1
3> H2.
2
4> H3.
3
5> Rest.
[4,5]

Why is it called "pattern matching"? Because it actually is matching patterns. Look:

6> [1,2,3,4,A] = [1,2,3,4,5].
[1,2,3,4,5]
7> A.
5
8> [1,2,3,4,A] = [1,2,3,4,6].
** exception error: no match of right hand side value [1,2,3,4,6]

In the first one we did what effectively amounts to an assertion that the list would start with [1,2,3,4] and that the fifth value could be anything at all, but please bind it into the unbound variable A. In the second one we did the same thing except that A is now bound so we're looking explicitly for the list [1,2,3,4,5] (because A is now 5).

JUST MY correct OPINION
  • 35,674
  • 17
  • 77
  • 99
2

In Clojure it would be called destructuring. Simple example:

(let [[foo bar] ["foo" "bar"]]
  (println "I haz" foo "and" bar))

It's also often used in function definitions, e.g. the following destructures a single point argument into x and y components:

(defn distance-from-origin [[x y]]
  (sqrt (+ (* x x) (* y y))))

You can also use the same technique to destructure nested data structures or key/value associative maps.

mikera
  • 105,238
  • 25
  • 256
  • 415