A function that computes the maximum of two integers can be written as:
function Max(X, Y : integer) return integer is
if X < Y then
return Y
else
return X
This same logic applies to other numeric types as well, so we might
be tempted to use the number generic type we used in the
factorial example. However, we can compare things that
are not numbers (for instance text, sorted lexically). All we need is
a < operator. Defining a
validated generic type allows us to
check for the operator before any instantiation. We can name that
generic type ordered:
generic type ordered if
X, Y : ordered
Test : boolean := X < Y
function Max(X, Y : ordered) return ordered is
if X < Y then
return Y
else
return X
In many cases, it is useful to compare more than two values. Assuming
an order where the maximum can be computed by comparing values two at
a time (there are order relations where this wouldn't work, for
instance "is a descendant of"), we can extend the Max function
to take an arbitrary number of arguments:
function Max(X : ordered) return ordered is
return X
function Max(X : ordered; ...) return ordered is
result := Max(...)
if result < X then
result := X
The definition above can be used to compare arbitrary sets of values:
X : real := Max(1.5, 2.6, 3.9)
Y : integer := Max(1,3,5,6,7,9)
Z : text := Max("Hello", "World")
It is possible to add other partial definitions of Max so that
elements of the argument list can be containers themselves. For
instance:
function Max(C : container of ordered; ...) return ordered is
result := Max(...)
X : ordered
for X in C loop
result := Max(X, result)
With such an additional definition, it becomes possible to write:
X, Y, Z : real
A, B : array[1..7] of real
TheMax : real := Max(X, A, Y, B, Z)
An interesting exercise left for the reader is to compare the
code representation above to representations of the same
concept in other languages, in particular using
Concept Programming metrics.
