loop allows the construction of recursive queries, using
Postgres' 
WITH RECURSIVE under the hood. The first
argument to 
loop is what the Postgres documentation refers to
as the "non-recursive term" and the second argument is the "recursive
term", which is defined in terms of the result of the "non-recursive
term". 
loop uses 
UNION ALL to combine the recursive
and non-recursive terms.
Denotionally, 
loop s f is the smallest set of rows
r such that
r == s `unionAll` (r >>= f)
Operationally, 
loop s f takes each row in an initial
set 
s and supplies it to 
f, resulting in a new
generation of rows which are added to the result set. Each row from
this new generation is then fed back to 
f, and this process
is repeated until a generation comes along for which 
f
returns an empty set for each row therein.