Goal
Use a record to bundle named fields, read and set them with ., and check
which fields exist - the right container when position-in-a-list would be
fragile.
Concept
A record is GAP's key→value structure, written rec( a := 1, b := "x" ).
You reach a field by name with .: r.a. Where a list says "the third thing,"
a record says "the thing called top." Many GAP objects are records under the
hood, and library data (structural info, options to functions) is passed as
records. Records are mutable, like lists.
Commands to try
r := rec( name := "S4", order := 24, perfect := false );
A record with three fields. Inside rec( … ) the field assignments use :=.
r.order;
Expect 24. Dot-access by field name.
r.order := 240;
r;
Fields are mutable: reassigning r.order changes the record in place. (We lie to
it here just to see mutation; reset with r.order := 24;.)
RecNames(r);
Expect a list of the field names as strings, e.g.
[ "name", "order", "perfect" ]. Order of names is not guaranteed. Records are
keyed by name, not position. This is the point of a record vs. a list: you
never rely on "field number 2."
IsBound(r.order);
IsBound(r.degree);
Expect true then false. IsBound tests whether a field exists before you
touch it. Trying to read an unbound field is an error, which you can guard with IsBound.
r.degree := 2;
RecNames(r);
You can add fields after creation just by assigning them. Now degree exists.
Unbind(r.degree);
IsBound(r.degree);
Unbind removes a field; now false again. (Unbind also works on list slots.)
Predict-then-check
Predict each, then check:
g := rec( gens := [ (1,2,3), (1,2) ], deg := 3 );
Length(g.gens);
IsBound(g.size);
RecNames(g);
(Note the parentheses: the values given in gens are permutations, which we'll cover in Lesson 07. Here just treat them as opaque list entries.)
Exercise
- Build a record describing a group:
rec( name := "A5", aka := "Alt5", order := 60, perfect := true ). - Add a field
simple := trueafter creation. - Write a
ForAlloverRecNamesof your record that checks every field name has length ≥ 2. (Lengthof a string is its character count.) - Use
IsBoundto safely returnr.degreeif present and0if not, in a single expression (hint: GAP has no ternary; anif … then … else … fiinside a function comes in Lesson 06 - for now just show the twoIsBoundresults).
Pitfalls
- Reading an unbound field errors. Guard with
IsBoundwhen you're not sure the field is there (common when library functions return optional fields). - Field names are bare identifiers after
.and:=insiderec(…), butRecNamesreturns them as strings. Don't mixr.name(field) with"name"(string) :RecNamesgives the latter. - Records have no inherent field order; never depend on the order
RecNamesreturns. rec( a := 1 )uses:=for fields; a record is not a list and has no[i]indexing.- Like lists, records are references -
s := r; s.order := 9;mutatesrtoo. UseStructuralCopyfor an independent record.