F2.07 · part 1 of 3
Product types
A product type holds several values at once. A tuple bundles them by position; a struct bundles them by name. Either way every field is present together, and because each field varies independently, the number of distinct values is the product of the fields’ counts.
Tuples are quick and anonymous: {1, 2} is two values with no labels.
Structs add names and a type: %Point{x: 1, y: 2} says these two numbers are a point.
Both are immutable, so “changing” a field means building a new value with that field replaced.
Tuple or struct
The same pair of values can be a tuple or a struct. A tuple reads by position with
elem/2; a struct reads by name with the dot. Names cost a little ceremony and buy
clarity and a type tag.
Switch between the two encodings.
- product type
- several fields held together; its values are their product.
- tuple
- fields by position:
{1, 2}, read withelem/2. - struct
- fields by name with a type:
%Point{x: 1, y: 2}. - field
- one component of the product.
same data · positional or named
Idea
Position or name — the same product, indexed two different ways.
Elixir
A struct is a map under the hood, tagged with __struct__.
Tuples index by position, structs by name. Reach for a struct when the fields deserve names and a type.
Updating a field
Structs are immutable, so updating a field does not change the original — it builds a new struct that
shares the untouched fields. %{point | x: new} produces a moved point and leaves
point exactly as it was.
Set the new x and compare.
%{point | x: new} · a new struct, original intact
F1.04 · immutability
Update returns a new value; shared fields are not copied, only referenced.
Elixir
The | update form requires the key to already exist on the struct.
Updating a struct builds a new one with the change applied; the original is untouched.
Worked examples
Defining, building, updating, and nesting product types.