Overview

When dealing with multilayered data structures, it is often useful to assign different substructures to corresponding variables with one statement. This technique is called destructuring.

For example, a two-element tuple of values can be conveniently destructured to become two different named values using this statement:

bind [A,B] to ["hello", "world"]. // A becomes "hello", B becomes "world"

Destructuring in MUFL is supported in these contexts:

  • In the bind statement (described below).
  • In the scan statement, providing a way for you to destructure values retrieved at every iteration of the scan.
  • In the output section of transact statement, enabling you to destructure results of a transaction invocation on a nested packet.
  • In arguments to functions, where the argument can be transparently destructured into constituents in the header of the function declaration. This technique is called type destructuring because the destructuring syntax simultaneously declares appropriate types for the data expected by the function.
  • In the metadef statement, where type destructuring is also supported.

Basic Patterns

Name Pattern

A new name within the current scope can be used to destructure a value into a variable. Name patterns are the basic part of more complex patterns described below.

Tuple Pattern

The tuple pattern destructures a MUFL array, represented as an integer-keyed dictionary. For example:

Array = [ "a", "b", "c", "d", "e" ].
bind [first, second] to Array. // sequential pattern: first = "a", second = "b"

Map Pattern

The map pattern is used to destructure a dictionary or record:

Person = ( $first_name->"John", $last_name->"Doe", $Age->32 ). 
bind ($first_name->fname, $last_name->lname) to Person. // fname = "John", lname = "Doe"

Aggregate Patterns and Combining Patterns

Patterns can be combined and nested:

Person = ( $name->($first_name->"John", $last_name->"Doe"), $address->($number->"500", $street->"Connecticut st.", $town->"Cranford", $state->"NJ", $country->"USA")). 

bind ( $name->($first_name->fname), $address->($number->address_number )) to Person. // fname = "John", address_number = "500".

Sometimes it is useful to retain both the aggregate value and some of its constituent values from within the data structure. Expanding on the previous example:

Person = ( $name->($first_name->"John", $last_name->"Doe"), $address->($number->"500", $street->"Connecticut st.", $town->"Cranford", $state->"NJ", $country->"USA")). 

bind ( $name->name=($first_name->fname), $address->address=($number->address_number )) to Person. // In addition to the destructuring performed in the above example, we now also have variables name and address that contain the entirety of the corresponding subrecords.

Map and tuple patterns can be intermixed as needed:

Employees = [($first_name->"John", $last_name->"Doe"), ($first_name->"Bob", $last_name->"Jones")]. 
bind [($first_name->fname1, $last_name->lname1), ($first_name->fname2, $last_name->lname2)] to Employees.