ACCEPTABLE?: List Comprehensions?

Reinier Zwitserloot reinier at zwitserloot.com
Mon Mar 16 11:06:21 PDT 2009


Paulo, why do you feel such an edge case is crucial? Adding syntax for  
this makes the concept far more confusing (for the same reason perl's  
cartoon swearing is confusing: No guidance by keywords, lots of  
different forms that are all legal but slightly different).

Also, java does not support tuples, which is what that list  
comprehension you posted would output in other languages, IIRC.


The generator expression, as well as the filter expression(s), are  
just that: Expressions. Method calls are expressions, so they'd of  
course be legal.


Here's a syntax proposal for list comprehensions. I can spin a  
proposal around this, but this would be the meat and potatoes:

'[' GeneratorExpression ComprehensionSources ']'

GeneratorExpression: Any expression, of any type. The type of the  
entire list comprehension (which is an expression) is a List<T>, where  
T is the inferred type of the generatorexpression. Forcing a type is  
done in the usual way (with a cast).

ComprehensionSources: ComprehensionSource ComprehensionSources(opt)

ComprehensionSource: ';' 'for' VarDeclaration ':' SourceExpression  
SourceFilter(opt)

VarDeclaration: Variable Declaration's scope restricted to only the  
SourceFilter belonging to this ComprehensionSource, all SourceFilter  
expressions of any ComprehensionSources to the right of this one, and  
the GeneratorExpression. Scope ends with the list comprehension.

SourceExpression: Either an Iterable<T> or an array of T; 100%  
analogous to the legal expressions on the RHS of foreach blocks.

SourceFilter: 'if' FilterExpression.

FilterExpression: Any expression that results in a 'boolean' value.  
Evaluated for each iteration; iteration is not run through the  
generator expression if the FilterExpression returns true. If the  
SourceFilter is not specified, assume it reads "if true". (i.e. don't  
discard any iterations).

Multiple ComprehensionSources are treated like nested for loops, with  
the last ComprehensionSource serving as the innermost loop.

Therefore, the following list comprehension:
[ a + b + c ; for int a : intList if a > 5 ; for int  b : new int[]  
{1, 2, 3, 4, 5} ; for c : intList if a + c == 10]

gets translated to:

{
     List<Integer> list = new ArrayList<Integer>(); //from type of  
generator expression.
     for ( int a : intList ) { //copy/paste from ComprehensionSource
         if ( !(a > 5) ) continue; //copy paste from filter expression
         for ( int b : new int[] { 1, 2, 3, 4, 5} ) {
             for ( int c : intList ) {
                 if ( !(a + c == 10) ) continue;
                 list.add(a + b + c); //generator expression
             }
         }
     }
     list
}

Where you'll have to imagine for a moment that the above block is an  
expression that returns 'list' as its value.

Paulo, could you elaborate on the exact meaning of what you wanted?  
Can you do it with the above syntax?

  --Reinier Zwitserloot



On Mar 16, 2009, at 18:18, Paulo Levi wrote:

> I would love list comprehensions, but only if they were amenable to  
> using
> all kinds of statements there  (methods) and many comprehension  
> statements
> in one list.
>
> List<Integer> input ....
> List<Integer> out = [x + valueToAdd for x : input if x % 2 == 0; x +
> valueToAdd + 2 for x : input];
> Possibly this could be compressed for the same list (as here) to:
> List<Integer> out = [x + valueToAdd if x % 2 == 0, x + valueToAdd +  
> 2 for x
> : in];
> With only one iteration needed.
>
> Would LOVE this.
>




More information about the coin-dev mailing list