45.3 Identical Records

With the record assignment (see Record Assignment) it is possible to change a record. The ability to change an object is only available for lists and records. This section describes the semantic consequences of this fact.

You may think that in the following example the second assignment changes the integer, and that therefore the above sentence, which claimed that only records and lists can be changed, is wrong.

    i := 3;
    i :=  i + 1;

But in this example not the integer 3 is changed by adding one to it. Instead the variable i is changed by assigning the value of i+1, which happens to be 4, to i. The same thing happens in the following example

    r := rec( a := 1 );
    r := rec( a := 1, b := 2 );

The second assignment does not change the first record, instead it assigns a new record to the variable r. On the other hand, in the following example the record is changed by the second assignment.

    r := rec( a := 1 );
    r.b := 2;

To understand the difference first think of a variable as a name for an object. The important point is that a record can have several names at the same time. An assignment var := record; means in this interpretation that var is a name for the object record. At the end of the following example r2 still has the value rec( a := 1 ) as this record has not been changed and nothing else has been assigned to r2.

    r1 := rec( a := 1 );
    r2 := r1;
    r1 := rec( a := 1, b := 2 );

But after the following example the record for which r2 is a name has been changed and thus the value of r2 is now rec( a := 1, b := 2 ).

    r1 := rec( a := 1 );
    r2 := r1;
    r1.b := 2;

We shall say that two records are identical if changing one of them by a record assignment also changes the other one. This is slightly incorrect, because if two records are identical, there are actually only two names for one record. However, the correct usage would be very awkward and would only add to the confusion. Note that two identical records must be equal, because there is only one records with two different names. Thus identity is an equivalence relation that is a refinement of equality.

Let us now consider under which circumstances two records are identical.

If you enter a record literal then the record denoted by this literal is a new record that is not identical to any other record. Thus in the following example r1 and r2 are not identical, though they are equal of course.

    r1 := rec( a := 1 );
    r2 := rec( a := 1 );

Also in the following example, no records in the list l are identical.

    l := [];
    for i  in [1..10]  do
        l[i] := rec( a := 1 );
    od;

If you assign a record to a variable no new record is created. Thus the record value of the variable on the left hand side and the record on the right hand side of the assignment are identical. So in the following example r1 and r2 are identical records.

    r1 := rec( a := 1 );
    r2 := r1;

If you pass a record as argument, the old record and the argument of the function are identical. Also if you return a record from a function, the old record and the value of the function call are identical. So in the following example r1 and r2 are identical record

    r1 := rec( a := 1 );
    f := function ( r )  return r;  end;
    r2 := f( r1 );

The functions Copy and ShallowCopy (see Copy and ShallowCopy) accept a record and return a new record that is equal to the old record but that is not identical to the old record. The difference between Copy and ShallowCopy is that in the case of ShallowCopy the corresponding elements of the new and the old records will be identical, whereas in the case of Copy they will only be equal. So in the following example r1 and r2 are not identical records.

    r1 := rec( a := 1 );
    r2 := Copy( r1 );

If you change a record it keeps its identity. Thus if two records are identical and you change one of them, you also change the other, and they are still identical afterwards. On the other hand, two records that are not identical will never become identical if you change one of them. So in the following example both r1 and r2 are changed, and are still identical.

    r1 := rec( a := 1 );
    r2 := r1;
    r1.b := 2;

Previous Up Top Next
Index

GAP 3.4.4
April 1997