Records, comparing

Record variables are references to records, not the records themselves. This means that there are two different ways in which you might want to compare two record variables:

1. You might want to compare their identity: do the two variables refer to the same record?
2. You might want to compare their value: do the two records have the same value?

To discover if two different record variables reference the same record, you use the reference equality operator, ==:

declare type point
field integer x
field integer y

process
local point alpha
local point omega

set omega to alpha

do when omega == alpha
output "Alpha and omega refer to the same record.%n"
else
output "Alpha and omega refer to different records.%n"
done

To discover if two records have the same values you can do one of the following:

1. Compare the field values of the two record individually
2. Write a function to compare the values of the records
3. Overload the OmniMark comparison operators to compare the values of the records

The following example compares two records by comparing the field values directly:

set alpha:x to 2
set alpha:y to 4

set omega:x to 3
set omega:y to 9

do when omega:x = alpha:x & omega:y = alpha:y
output "The two records describe the same point.%n"
else
output "The two records describe different points.%n"
done

The next example defines a function to compare points:

define switch function same-point
(value point a,
value point b
) as
return a:x = b:x & a:y = b:y

process
...
do when same-point (alpha, omega)
output "The two records describe the same point.%n"
else
output "The two records describe different points.%n"
done

The function name "same-point" is somewhat ugly. What we really want is to use the "=" sign to test whether two points are the same. We can do this by overloading the "=" operator:

value point a = value point b
as
return a:x = b:x & a:y = b:y

process
...
do when alpha = omega
output "The two records describe the same point.%n"
else
output "The two records describe different points.%n"
done

Note that there are several possible meaning that could be associated with the idea that two records are "equal" to each other. The example above uses the most obvious one, that all the fields contain the same values. However, other interpretations of the idea of equality are possible. For example, consider a record type for a place, which contains the name of the place and its latitude and longitude:

import "omfloat.xmd" unprefixed

declare record place
field float latitude
field float longitude
field stream name

Suppose we have two place records:

process
local place ottawa
local place capital

set ottawa:latitude to 45.417
set ottawa:longitude to -75.700
set ottawa:name to "Ottawa, Ontario"

set capital:latitude to 45.417
set capital:longitude to -75.700
set capital:name to "the Capital of Canada"

What is the correct way to compare these two records? A straight field by field comparison will say that they are not equal, since the name fields do not match. However, the latitude and longitude values are the same, and the two different name values are actually two different names for the same place.

In comparing two place records, therefore, we may want to compare the latitude and longitude values and ignore differences in the name field. This may be a very useful function, because it will enable us to discover if two place names are actually the name of the same place:

value place a
=
value place b
as
return a:latitude = b:latitude & a:longitude = b:longitude

process
...
output ottawa:name
|| (ottawa = capital -> " is " | " is not ")
|| capital:name
|| "%n"

Related Topics