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
alert(a);

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).

Dmitry.

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to