The Predicate <tt>where</tt>

HANDBOOK / GENTLE PRIMER / Control Structures /

# The Predicate `where`

In the previous example, each alternative invoked a procedure `process` that defined the common result variable `C`. If no such action is adequate, we have to use something similar to specify the result.

Gentle has a predefined predicate `where` that merely copies its input to its output. It is defined for each type `T`

       'action' where(T -> T)
       'rule' where(X -> X)

This can be used to define variables. For example,

       where(red -> Col)

defines `Col` as `red`

Consider the predicate `max` with rules

       'rule' max(X, Y -> X): ge(X, Y)
       'rule' max(X, Y -> Y): lt(X, Y)

If we want to replace an invocation

       max(A, B -> C)

we can write

       (| ge(A, B) where(A -> C) || lt(A, B) where(B -> C) |)

Here, `C` is defined as the maximum of `A` and `B`.

In the example, an alternative was selected by giving a condition such as `ge` as a guard. If we wish to replace a predicate inline, the rules of which are selected by pattern matching, we have to use a different device.

Again, we can use the predefined predicate `where`. If we supply a pattern as the output value the input value is matched against this pattern. The pattern may contain variables, which are defined if matching succeeds. For examples,

       where(Col -> red)

succeeds if `Col` is `red`.

Consider the predicate `MapType(Type -> Rep)` with rules

       'rule' MapType(array(N,Type) -> Rep): ArrayType(N,Type -> Rep)
       'rule' MapType(int -> Rep): IntType(-> Rep)

An invocation

       MapType(Type -> Rep)

can be replaced by

       (|
          where(Type -> array(N, Type))
          ArrayType(N, Type -> Rep)
       ||
          where(Type -> int)
          IntType(-> Rep)
       |)

Here, `Rep` is defined in both alternatives, and therefore by the whole alternative statement. `N` and `Type` are variables that are local to the first alternative.