List comprehensions - vilinski/nemerle GitHub Wiki

Example

$[ (x, y) | x in l1, x > 3, y in l2, x < y ]
to:
mutable res = [];
foreach (x in l1)
  when (x > 3)
    foreach (y in l2)
      when (x < y)
        res ::= (x, y);
res.Rev ()

Generally

$[ expr | cond0, x1 in c1, cond1, ..., xN in cN, condN ]
to:
mutable res = [];

when (cond0)
  foreach (x1 in c1)
    when (cond1)
      ...
      foreach (xN in cN)
        when (condN)
          res ::= expr;
res.Rev ()

Ranges

Collections can be ranges of the form [x, y .. z], were x, y and z are expressions. This stands for:

def delta = y - x;
[x, x + delta, x + 2*delta, ..., x + n*delta]
where x + n*delta <= z (for greatest possible n), or if delta is negative, x + n * delta >= z (for greatest possible n).

There is also a simpler form [x .. y] which is a shorthand for [x, x+1 .. y].

For example:

[1 .. 3] == [1, 2, 3]
[1,3 .. 9] == [1, 3, 5, 7, 9]
[1,3 .. 10] == [1, 3, 5, 7, 9]
[5 .. 1] == []
[5,4 .. 1] == [5, 4, 3, 2, 1]

Expressions x, y and z in [x, y .. z] are executed once for a given range usage, and in the order specified. So the program:

def foo(k)
  WriteLine ($"foo($k)")
  k

def bar(k)
  WriteLine ($"bar($k)")
  k

WriteLine ($[ (x,y) | x in [foo (1), foo (3) .. foo (7)],
                      y in [bar (2), bar (4) .. bar (8)] ])

will print:

foo(1)
foo(3)
foo(7)
bar(2)
bar(4)
bar(8)
bar(2)
bar(4)
bar(8)
bar(2)
bar(4)
bar(8)
bar(2)
bar(4)
bar(8)
[(1, 2), (1, 4), (1, 6), (1, 8), (3, 2), (3, 4), (3, 6), (3, 8), 
 (5, 2), (5, 4), (5, 6), (5, 8), (7, 2), (7, 4), (7, 6), (7, 8)]
⚠️ **GitHub.com Fallback** ⚠️