Day 2 meeting notes
Dmitry A. Soshnikov
dmitry.soshnikov at gmail.com
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
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.
More information about the es-discuss
mailing list