ACCEPTABLE?: List Comprehensions?
Reinier Zwitserloot
reinier at zwitserloot.com
Sat Mar 14 09:15:46 PDT 2009
Ah, list comprehensions. I forgot them on my list. They aren't
closures, but you can do quite a few closure use-cases with them, and
are a lot easier to understand. The draft proposal looks good (but is
incomplete; it doesn't mention any JLS chapters, for example), but
there's one big issue it doesn't mention: If the list comprehensions
return Iterables, then the generating expression, as well as the
filter expressions, are effectively 'closures' and get all the
complications that stem from this. For example, you would not be able
to use non-final variables in there, unless we change the rules
regarding usage of non-finals in 'closures', which involves a
significant change for the JVM (it has to declare that variable on the
heap and not on the stack).
Generating the entire list on the spot has none of those issues, and
turns the entire proposal into syntactic sugar + a new utility class
in the spirit of Collections and Arrays, named 'Iterables'. That's all.
Joe: If a list comprehension proposal is written that involves
(extensive) syntax sugar + 1 new class file and nothing else, would
they have a chance?
Example desugaring:
public List<Integer> findEvensAndAdd(List<Integer> in, int valueToAdd) {
List<Integer> out = [x + valueToAdd for x : in if x % 2 == 0];
return out;
}
becomes:
public List<Integer> findEvensAndAdd(List<Integer> in, int valueToAdd) {
List<Integer> $uniqueName = new ArrayList<Integer>();
for ( int x : in ) {
if ( !(x % 2 == 0) ) continue;
$uniqueName.add(x + valueToAdd);
}
$uniqueName = Collections.unmodifiableList($uniqueName);
List<Integer> out = $uniqueName;
return out;
}
In other words, a uniquely named list is created, the variable
declaration + source list is moved straight into a foreach loop
clause, then the filter statement(s) are all concatenated via if ( !
CLAUSE1 || !CLAUSE2 || !CLAUSE3 ) continue, and finally the generator
expression is used to generate a value, which is added to the uniquely
named list. Finally, the list is turned into an unmodifiableList to
avoid having to specify exactly what happens or can't happen when you
add/remove/change the list.
Definitive assignment follows from this desugaring; any variable read
out anywhere in the list comprehension (in any of the 3 places where
they can occur; generator, sources, filters) are presumed to be read
(and thus need to be guaranteed initialized), any variable set
anywhere in the list comprehension is presumed to Maybe occur - so
it's enough to trigger 'final' warnings, but its not enough to
guarantee initialization. The only exception is the sources list,
which is like a normal statement (guaranteed to be run, exactly once).
the type of the expression is List<X> where X is the type of the
generating expression.
--Reinier Zwitserloot
Like it? Tip it!
http://tipit.to
More information about the coin-dev
mailing list