eclipse-archived / ceylon

The Ceylon compiler, language module, and command line tools
http://ceylon-lang.org
Apache License 2.0
399 stars 62 forks source link

Sequence comprehensions #3188

Closed CeylonMigrationBot closed 9 years ago

CeylonMigrationBot commented 12 years ago

[@gavinking] So, it appears to me that we've moved away from the idea of Smalltalk-style arguments for invocation of higher-order functions, and that everyone seems to want a much more conventional syntax for anonymous functions inside positional argument lists (see #3160). I can live with that. But if that's the case, then I'm going to have to insist that we at least need a specialized syntax for comprehensions. There's many many possible variations of this syntax, but the two possibilities that I think would make most sense are the following:

{ (x**2+y**2)**0.5: x in 0..100 && x%10==0, y in -10..+10 && y%2==0 }

or

{ (x**2+y**2)**0.5: x in 0..100, x%10==0; y in -10..+10, y%2==0 }

I don't have an especially strong preference between these two options. I think the first is more consistent with the rest of our notation, and the second is perhaps slightly easier on the eyes. The second option is also a bit better from a grammar point of view.

Of course, there is also an argument for something like the following syntax:

{ (x**2+y**2)**0.5 for (x in 0..100) if (x%10==0) for (y in -10..+10) if (y%2==0) }

But in this case, I don't think the extra verbosity contributes to readability.

Note that since this is probably something I can desugar in the frontend, we could probably have this feature almost immediately.

Thoughts?

UPDATE:

Note that this syntax would be allowed to appear in two places:

  1. where sequence enumerations appear, which would instantiate an ArraySequence, and
  2. in place of a named argument list, producing an Iterable (or perhaps some kind of lazy sequence).

So you would be able to write:

HashMap { p.name->p.address: p in people }

[Migrated from ceylon/ceylon-spec#82] [Closed at 2012-05-04 01:51:59]

CeylonMigrationBot commented 12 years ago

[@gavinking] Y'know what, I don't think we need this feature. I mean, it seems to me that I would prefer to read:

value total = sum ( for (x in xs) x );
if ( every ( for (x in xs) x>0 ) )  { ... }
if ( any ( for (x in xs) x>0 ) ) { ... }

Than:

value total = for (y=0.0; x in xs) y+x;
if ( for (all=false; x in xs) all && x>0 ) { ... }
if ( for (any=false; x in xs) any || x>0 ) { ... }

Is there something I'm missing? Some kind of common use of fold() that can't be nicely pulled out into a utility function?

CeylonMigrationBot commented 12 years ago

[@RossTate] I think the

order.items.foldl(0) { next(Integer prev, Item item) = prev + item.produce.price*item.quantity }

syntax already available should be good enough for miscellaneous cases. If not, we can always try adding this feature later once we know what the demand looks like.

CeylonMigrationBot commented 12 years ago

[@gavinking] Closing this because the syntax is nailed down and activity has moved to #3390.