list comprehension bug ?

Thomas Lindgren thomasl_erlang@REDACTED
Fri Jul 11 10:14:45 CEST 2003

--- Håkan_Stenholm <hakan.stenholm@REDACTED>
> I encountered a odd list comprehension bug (R9B-0,
> MacOS X 10.2.6):
> [Pos || map_get(Map,Pos), Pos <- Neighbours].
> results in a "variable 'Pos' is unbound" compile
> error, but changing 
> the order of the generator and predicate makes the
> compile error go 
> away:
> [Pos || Pos <- Neighbours, map_get(Map,Pos) ].

The generators/filters sequence of a list
comprehension is evaluated left to right, so the
compiler behaviour is correct. The documentation is a
bit unclear on this point, so it's a natural mistake
to make:

section 3.2)

"The scope rules for variables which occur in list
comprehensions are as follows:

    * all variables which occur in a generator pattern
are assumed to be "fresh" variables

    * any variables which are defined before the list
comprehension and which are used in filters have the
values they had before the list comprehension

    * no variables may be exported from a list

Thus, your first example might be interpreted to be
correct using those rules, since nothing says the
"fresh" variable Pos is only visible "to the right" of
the generator.

In the same vein, we can also write the unintuitive:

% example 1
> Y = [["abc", "def", "ghi"]], 
  X = [["123", "456"], ["789"]], 
  [ X || X <- X, Y <- X, X <- Y ].

or even

% example 2
> X = [["123", "456"], ["789"]], 
  [ X || X <- X, X <- X, X <- X ].

which actually work. But without a left-to-right
evaluation order, it's not so clear what should
happen. Example 1 could yield two different results,
depending on evaluation order (try reversing the order
of the generators).

The examples in the documentation do imply a
left-to-right evaluation order and scoping, and it is
the "standard" way to define list comprehensions. But
it should of course be documented explicitly.


Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.

More information about the erlang-questions mailing list