This construction is an expression that temporarily assigns the identifier to
the second expression and then
yields the value of the first expression. The identifier may be referred
to in the first expression and it will equal the value of the second
expression.
The token := can be used as a synonym for is.
The scope of the identifier is the where ... is construction
alone except for when the construction is part of an expression list --- see
below.
The where operator is left-associative. This means that there
can be multiple uses of where ... is constructions and each
expression can refer to variables bound in the enclosing constructions.
Another important feature is found in a set or sequence constructor.
If there are where ... is constructions in the predicate, then any variables bound in
them may be referred to in the expression at the beginning of the constructor.
If the whole predicate is placed in parentheses, then any variables bound
in the predicate do not extend to the expression at the beginning of
the constructor.
The where operator also extends left in expression lists.
That is, if there is an expression E in a expression list which is a
where construction (or chain of where constructions), the identifiers
bound in that where construction (or chain) will be defined in all
expressions in the list
which are to the left of E. Expression lists commonly arise as argument
lists to functions or procedures, return arguments, print statements
(with or without the word `print') etc.
A where construction also overrides (hides) any where construction to the
right of it in the same list.
Using parentheses around a where expression ensures that the identifiers
bound within it are not seen outside it.
The following examples illustrate simple uses of
where ... is.
> x := 1;
> x where x is 10;
10
> x;
1
> Order(G) + Degree(G) where G is Sym(3);
9
Since
where is left-associative we may have multiple uses of it.
The use of parentheses, of course, can override the usual associativity.
> x := 1;
> y := 2;
> x + y where x is 5 where y is 6;
11
> (x + y where x is 5) where y is 6; // the same
11
> x + y where x is (5 where y is 6);
7
> x + y where x is y where y is 6;
12
> (x + y where x is y) where y is 6; // the same
12
> x + y where x is (y where y is 6);
8
We now illustrate how the left expression in a set or sequence constructor
can reference the identifiers of
where constructions in the predicate.
> { a : i in [1 .. 10] | IsPrime(a) where a is 3*i + 1 };
{ 7, 13, 19, 31 }
> [ <x, y> : i in [1 .. 10] | IsPrime(x) and IsPrime(y)
> where x is y + 2 where y is 2 * i + 1 ];
[ <5, 3>, <7, 5>, <13, 11>, <19, 17> ]
We next demonstrate the semantics of
where constructions inside
expression lists.
> // A simple use:
> [a, a where a is 1];
[ 1, 1 ]
> // An error: where does not extend right
> print [a where a is 1, a];
User error: Identifier 'a' has not been declared
> // Use of parentheses:
> [a, (a where a is 1)] where a is 2;
[ 2, 1 ]
> // Another use of parentheses:
> print [ a, (a where a is 1) ];
User error: Identifier 'a' has not been declared
> // Use of a chain of where expressions:
> [ <a, b>, <b, a> where a is 1 where b is 2 ];
[ <1, 2>, <2, 1> ]
> // One where overriding another to the right of it:
> [ a, a where a is 2, a where a is 3 ];
[ 2, 2, 3 ]
[Next][Prev] [Right] [Left] [Up] [Index] [Root]