"Tuple" is a mathematical word for a sequence of values. It is a generalization of such English words as:
"duple" (two of something), "triple" (three ... ), "quadruple" (four ... ) "quintuple" (five ... ) "sextuple" (six ... ) "septuple" (seven ... ) "octuple" (eight ... )
We use "tuple" to refer to all of these plus all other lengths.
Mythryl tuples are written with the values wrapped in parentheses and separated by commas:
("this", 123) # A length-two tuple. (0, 1, "infinity") # A length-three tuple. ("string", 'a', 1, 1.0) # A length-four tuple.
Tuples are near and dear to Mythryl’s heart. They are the cheapest, simplest compound datastructure, the material from which almost all else is fashioned.
In more formal language, a Mythryl tuple is a heterogeneous collection of values stored contiguously in a small chunk of memory and accessed by slot number. Mythryl attempts to make creation of tuples as cheap as possible. The Mythryl implementation can create tuples roughly as cheaply as C can push a stackframe.
linux$ my eval: a = ("Windward Passage", 13.5, 9318.0); eval: #1 a; "Windward Passage" eval: #2 a; 13.5 eval: #3 a; 9318
A Mythryl record is similarly a heterogeneous collection of values stored contiguous in a small chunk of memory. The difference is that record values are accessed by name instead of by slot number:
linux$ my eval: a = { name => "Windward Passage", length_overall => 13.5, displacement => 9318.0 }; eval: a.name; "Windward Passage" eval: a.length_overall; 13.5 eval: a.displacement; 9318.0 eval: .name a; "Windward Passage" eval: .length_overall a; 13.5 eval: .displacement a; 9318.0
As the above example shows, record fields can be accessed by name via the record.field syntax familiar from C. This is usually the most readable syntax.
The final three expressions in the above example show that record fields can also be accessed by applying the fieldname as a function.
This may be useful, for example, in conjunction with map, extracting a given field from a list of records:
eval: a = { name => "Windward Passage", length_overall => 13.5, displacement => 9318.0 }; eval: b = { name => "Gay Deceiver", length_overall => 130.5, displacement => 491634.8 }; eval: c = [ a, b ]; eval: map .name c; ["Windward Passage", "Gay Deceiver"] eval: map .length_overall c; [13.5, 130.5] eval: map .displacement c; [9318.0, 491634.8]
Value order is significant in a tuple: (1,2,3) is not the same tuple as (3,2,1).
Field order within a record, by contrast, is of no signficance: { first=>"John", last=>"Doe" } is exactly equivalent to { last=>"Doe", first=>"John" }.
Semantically, Mythryl records and tuples are very closely related. In fact, internally, the Mythryl compiler converts record expressions into tuple expressions very early in processing and makes no distinction between them thereafter.
Whether to use tuples or records in a given situation is thus often more a matter of taste than anything else.
Records and tuples are the cheapest, simplest Mythryl datastructures. They are the bricks and mortar from which higher level datastructures are built.
Mythryl programs create and discard enormous numbers of tuples and records as they run. Mythryl makes creating them as cheap as pushing a stackframe in C; it is expected and encouraged that the Mythryl programmer think as little of creating a new tuple or record as does the C programmer of doing a function call.
As the above examples hint, tuples and records are particularly powerful in combination with lists. Lists excel at handling variable-length homogeneous collections; records and tuples excel at handling fixed-length heterogeneous collections.