Comprehensions
Synopsis
Comprehensions for generating values.
Description
Comprehensions are a notation inspired by mathematical set-builder notation
and list comprehensions
that help to write succinct definitions of lists and sets. They also resemble SELECT
queries as found in a language like SQL quite a bit.
Rascal generalizes comprehensions in various ways. Comprehensions exist for lists, sets and maps, and even for general values. A comprehension consists of an expression that determines the successive elements to be included in the result and a list of enumerators and tests (boolean expressions). The enumerators produce values and the tests filter them.
See Comprehensions, List Comprehension, Set Comprehension, and Map Comprehension for details. Have a look at Reducer to use a comprehesion to construct anything else but a list, set or map.
Examples
A standard example is
rascal>{ x * x | int x <- [1 .. 10], x % 3 == 0 }
set[int]: {9,81,36}
i.e., the squares of the integers in the range [ 1 .. 10 ]
that
are divisible by 3. A more intriguing example (that we do not give in full detail) is
{name | /asgStat(Id name, _) <- P}
which traverses program P
(using the descendant match operator /
, see Patterns)
and constructs a set of all identifiers that occur on the left hand
side of assignment statements in P
.
Benefits
- Using comprehensions and pattern matching you can
query
any tree-like object and turn it into a graph or relation
Pitfalls
- Comprehensions can be arbitrarily nested, but that does not improve the readability of your code. Better split complex queries up into separate lines or even separate functions.