Day 2 meeting notes

Dmitry A. Soshnikov dmitry.soshnikov at
Fri Jul 30 13:38:08 PDT 2010

On 30.07.2010 23:06, felix wrote:
> On 7/29/10 16:55, Oliver Hunt wrote:
>> On Jul 29, 2010, at 2:47 PM, Waldemar Horwat wrote:
>>> Comprehensions:  To be useful, need to have a bunch of basic helpers
>>> such as range(), properties(), values(), etc. with short names that
>>> can be used to construct comprehensions.  These will be added to the
>>> proposal.
>>> Would like to be able to interleave for and if clauses:
>>> [x*y for (x in range(...)) if (isprime(x)) for (y in range(x+1...)) if
>>> (isprime(y))]
>> I keep seeing code like this, I simply don't see it as viable to have 
>> "for (.. in ...)" sometimes enumerate property names, and some times 
>> enumerate keys, it seems like it could be both confusing and error 
>> prone.  esp. given the simplest example: [x for (value in [1,2,3])] 
>> you would not get the desired behaviour, unless in comprehensions 
>> for(in) behaves differently from everywhere else.
>> It seems far better to just define a distinct syntax for enumerating 
>> values of an object.
> actionscript 3 has
>   for (key in a) {}
>   for each (val in a) {}

Not only ActionScript, but JavaScript too (e.g. SpiderMonkey 1.7).

Another thing to mention regarding array comprehensions is /pattern 
matching/ (in less common, but related to JS, case -- /destructing 
assignment/). Currently, it's implemented in JS 1.7 in simple 
for/each-in loops:

for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) {
   alert(x); // 10, 20, 30

Yes, it can be useful to pattern match {a: x} extracting a value of the 
"a" property into the "x" variable. Array comprehensions of JS 1.7 in 
contrast with a loop do not have such sugar:

let a = [x for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x > 2)]; 
// SyntaxError

Also using pattern matching, it's useful sometimes to filter needed 
values of an array in the pattern matching parameter itself, but not 
using filter section (actually, it's hard to use filter section to 
filter exactly values which are not of the needed structure). For 
example (code on Erlang with its list comprehensions):

List = [{1,2}, skip, {3,4}],

FilteredList = [X + Y || {X, Y} <- List].

Result is: [3, 7]. Pattern matching filtered atom `skip' and took only 
{X, Y} structures (1st and 3rd elements in list) extracting values into 
the X and Y variables.

This is useful feature, I was needed it on practice. In contrast 
lists:map + lists:filter (that's desugared list comprehensions) cannot 
handle this case, because for the `skip' atom will be `bad match' error 
and we can't map a list the same elegant as with list comprehension:

List = [{1,2}, skip, {3,4}],
lists:map(fun({X, Y}) -> X + Y end, List).  % bad_match error for the 
second element - `skip' atom

Syntactically JavaScript has similar construction, but semantically 
result differs:

for each ({a: x, b: y} in [{a: 10, b: 20}, "skip", {a: 30, b: 40}]) {
   alert(x, y); // 10, 20 | undefined, undefined | 30, 40

String "skip" isn't pattern matched, but the object is created with 
`undefined' values for x and y. And again for array comprehensions this 
shows SyntaxError (that, for consistency with for/each-in loop should not).


More information about the es-discuss mailing list