for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)

# Brendan Eich (14 years ago)

The recommended practice when writing for-in loops in JS today is to write:

for (i in o) { if (o.hasOwnProperty(i)) { body } }

Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter).

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { body }

This is a small thing but it might pay off in the long run.

# Felipe Gasper (14 years ago)

On 11/8/11 2:49 PM, Brendan Eich wrote:

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { /body/ }

This is a small thing but it might pay off in the long run.

This is a fantastic idea, IMO.

The hasOwnProperty() thing is buggy if you create a “hasOwnProperty” property on the object, and it’s wordy besides.

# John J Barton (14 years ago)

On Tue, Nov 8, 2011 at 12:49 PM, Brendan Eich <brendan at mozilla.com> wrote:

The recommended practice when writing for-in loops in JS today is to write:   for (i in o) {     if (o.hasOwnProperty(i)) {       body     }   } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':   for own (i in o) {     body   } This is a small thing but it might pay off in the long run.

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

I would use |for own| if it existed, solely to avoid thinking about overhead and because single stepping would work better.

jjb

# Axel Rauschmayer (14 years ago)

I see two domains for the concept of “own” properties:

  1. Meta-programming.
  2. Using objects as dictionaries.

Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts?

I also like the Python-style iterator-based approach, e.g. something like the following:

 for ([key,value] on pairs(obj)) {
 }
# Jeremy Ashkenas (14 years ago)

On Tue, Nov 8, 2011 at 3:49 PM, Brendan Eich <brendan at mozilla.com> wrote:

for own (i in o) { body }

This is a small thing but it might pay off in the long run.

This is a very useful feature ... but for better or for worse, also shows off how much paren-free would help things. "for own key in object {" reads well, whereas "for own (key in object) {" reads strangely, because the adjective "own" naturally belongs next to it's nown "key", without an interloping lparen.

# Timmy Willison (14 years ago)

Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that.

jsperf.com/hasownproperty-vs-for-in/4#c300

# Claus Reinke (14 years ago)

for own (i in o) { body }

What happened to @iter.keys and 'for (key of keys) {}'?

harmony:iterators

Claus clausreinke.github.com, clausreinke.github.com/js-tools

# Quildreen Motta (14 years ago)

On 08/11/11 18:49, Brendan Eich wrote:

The recommended practice when writing for-in loops in JS today is to write:

for (i in o) { if (o.hasOwnProperty(i)) { /body/ } }

Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter).

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { /body/ }

This is a small thing but it might pay off in the long run.

Isn't that just:

Object.keys(o).forEach(function(i){ body })

Iirc, that's faster than a for..in loop with filter in v8 due to the aggressive function inlining, not sure about SpiderMonkey. It also reads better and it's more composable -- for me, at least.

I do use keep `var keys = Object.keys' and other hand aliases though.

It still seems to me it's overkill to add special syntax (and a new reserved word, yuck!) to something that isn't really worth it, given the Object API already provides those methods.

Also, are Object.values and Object.items standardised in ES.next. They're quite useful?

# Quildreen Motta (14 years ago)

On 08/11/11 19:19, Axel Rauschmayer wrote:

I see two domains for the concept of “own” properties:

  1. Meta-programming.

Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/

  1. Using objects as dictionaries.

Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts?

I would think most of the cases where objects are used as dicts would be solved by using Object.create(null)', today on ES5-compliant engines. Except for the nasty, nastyproto' on engines that use that magic, but then you can proxy property access/assignment. It's quite ad-hoc, but works.

The dicts proposal looks nice though.

# David Bruant (14 years ago)

Le 08/11/2011 21:49, Brendan Eich a écrit :

The recommended practice when writing for-in loops in JS today is to write:

for (i in o) { if (o.hasOwnProperty(i)) { /body/ } }

As said in the thread your forked from, this practice is often recommended to not enumerate Object.prototype methods (rather than enumerating only own properties)

Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter).

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { /body/ }

This is a small thing but it might pay off in the long run.

Why would developers use for own while they currently do not use hasOwnProperty? I really am skeptical on this. Enumeration of own enumerable properties can be done with Object.keys. Why not encourage people to use this? Are you also proposing an addition of for own (... of ...) if for-own-in and for-of are both accepted?

# Axel Rauschmayer (14 years ago)

I see two domains for the concept of “own” properties:

  1. Meta-programming. Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/

Whenever you copy properties from one object to another one, you are usually doing meta-programming (unless you use an object as a dictionary).

  1. Using objects as dictionaries.

Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? I would think most of the cases where objects are used as dicts would be solved by using Object.create(null)', today on ES5-compliant engines. Except for the nasty, nastyproto' on engines that use that magic, but then you can proxy property access/assignment. It's quite ad-hoc, but works.

The dicts proposal looks nice though.

Modulo what Allen is proposing for [] to keep program domain and data domain separate. Then dicts can actually get a size() method.

# John J Barton (14 years ago)

On Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison <timmywillisn at gmail.com> wrote:

Yes, I think JS needs something like this.  This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar.  But I don't know how realistic it is to hope for that. jsperf.com/hasownproperty-vs-for-in/4#c300

Added case Object.keys().forEach:

jsperf.com/hasownproperty-vs-for-in/7

Of course results depend more on browser than form of the loop...

jjb

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 1:19 PM, Axel Rauschmayer wrote:

I see two domains for the concept of “own” properties:

  1. Meta-programming.
  2. Using objects as dictionaries.

Thanks, good to focus on use-cases. Both would like shorthand and freedom from Object.prototype.hasOwnProperty tamper-proofing.

Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts?

We don't know how dicts will fare. Making progress with for own does not interact badly with dicts if we spec them to be for-in'able -- for own (k in d) for d a dict should work, just as for objects.

I also like the Python-style iterator-based approach, e.g. something like the following:

 for ([key,value] on pairs(obj)) {
 }

s/on/of/

I like that too, and we have keys/values/items in the strawman (items, not pairs -- after Python). These are own-only. But plain old for-in still benefits from own.

If 'for (let k of keys(obj))' is good enough to de-motivate 'for own (let k in obj)', great. The latter is only slightly shorter (two chars, the way I've coded it with space after own, for the parens saving), but more important: it is a simpler upgrade to existing for-in loops that otherwise need rewriting.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 1:19 PM, Jeremy Ashkenas wrote:

On Tue, Nov 8, 2011 at 3:49 PM, Brendan Eich <brendan at mozilla.com> wrote:

for own (i in o) { body }

This is a small thing but it might pay off in the long run.

This is a very useful feature ... but for better or for worse, also shows off how much paren-free would help things. "for own key in object {" reads well, whereas "for own (key in object) {" reads strangely, because the adjective "own" naturally belongs next to it's nown "key", without an interloping lparen.

You'll be glad to know I'm still working on paren-free. You will be unsurprised to hear it needs even more newline significance to overcome some issues Waldemar Horwat pointed out.

I give paren-free very long odds for ES.next. Better to design and prototype it, get it in as an opt-in for Narcissus, SpiderMonkey and other implementations to enable user-testing.

Good news for ES.next remains: array comprehensions and generator expressions use only paren-free for/of syntax.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 1:48 PM, Claus Reinke wrote:

for own (i in o) { body }

What happened to @iter.keys and 'for (key of keys) {}'?

Still there, but write it out fully, to compare to the cited text:

import keys from "@iter"; for (i of keys(o)) { body }

Unless we default-import a standard prelude, this is a bit much compared to add own as a modifier after for in for/in (not for/of) loops.

# Quildreen Motta (14 years ago)

On 08/11/11 20:22, Axel Rauschmayer wrote:

I see two domains for the concept of “own” properties:

  1. Meta-programming. Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/

Whenever you copy properties from one object to another one, you are usually doing meta-programming (unless you use an object as a dictionary).

Hm, I see. I always tend to think of meta-programming in the Lisp sense (macros that mutate the AST), but I guess I see the point in generating objects dynamically.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 2:03 PM, Quildreen Motta wrote:

On 08/11/11 18:49, Brendan Eich wrote:

The recommended practice when writing for-in loops in JS today is to write:

for (i in o) { if (o.hasOwnProperty(i)) { body } }

Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter).

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { body }

This is a small thing but it might pay off in the long run. Isn't that just:

Object.keys(o).forEach(function(i){ body })

Good grief. Your "just" is pointing the wrong way. The longer, more contingent in terms of mutable global and Object property bindings, form is not the primitive one.

Iirc, that's faster than a for..in loop with filter in v8 due to the aggressive function inlining, not sure about SpiderMonkey.

It's not necessarily faster or slower, implementations vary. And what is the length of the necessarily-reified, returned keys array? Have you tested large objects?

You can use it if you like (performance is not usually overriding).

It also reads better and it's more composable -- for me, at least.

YMMV.

Again, ES.next already will support

for (let i in keys(o)) { body }

if you have keys imported. There is no "there must be only one way to say things in JS" dogma in JS; this is a feature.

I do use keep `var keys = Object.keys' and other hand aliases though.

It still seems to me it's overkill to add special syntax (and a new reserved word, yuck!)

No new unconditionally reserved word. Rather, contextually reserved after 'for', no impact on other uses of 'own'. ECMA-357 (E4X) did likewise with 'for each(... in ...)'.

Overkill may be writing a function around one's code just to call an array extra on a reified array of keys. Iterators can be much faster.

Here's another, more real-world concern: wrapping //body// in function (){...} breaks the principle of equivalence (TCP) and people can and do fail to capture the outer |this|, e.g. by var self = this, and propagate it to the revised //body// as self. Tom Van Cutsem had such a bug, Mark Miller has seen such bugs. They are serious runtime type/instance confusion bugs, possibly with security implications.

(Block-lambdas would help here, shameless plug -- but let's stay on target.)

to something that isn't really worth it, given the Object API already provides those methods.

for-in loops are quite commonly used. Object.keys is new and while people polyfill it, practice varies wildly.

Also, are Object.values and Object.items standardised in ES.next. They're quite useful?

They are not object methods, and you're mistaking Object.keys for the "@iter" module's keys function.

Returning iterators instead of eager arrays is a serious perf win for large objects.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 2:16 PM, David Bruant wrote:

Le 08/11/2011 21:49, Brendan Eich a écrit :

The recommended practice when writing for-in loops in JS today is to write:

for (i in o) { if (o.hasOwnProperty(i)) { body } } As said in the thread your forked from, this practice is often recommended to not enumerate Object.prototype methods (rather than enumerating only own properties)

Really? That is not its effect of course, and that is not really important in distinction to not enumerating any non-own properties.

Where have you seen this recommended but with the mistaken idea that it filters only Object.prototype enumerable properties? Remember, for over five years extending Object.prototype has been verboten. The really issue is, e.g., PrototypeJS extending Array.prototype (not that there's anything wrong with that!).

Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter).

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) { body }

This is a small thing but it might pay off in the long run. Why would developers use for own while they currently do not use hasOwnProperty?

Several reasons come to mind:

  • shorter and easier to type.
  • faster by definition.
  • I know CoffeeScript, I'm writing raw JS for a new gig that requires it.

I really am skeptical on this. Enumeration of own enumerable properties can be done with Object.keys. Why not encourage people to use this?

Because

  1. It eagerly reifies an array of keys, which can hurt for high-call-frequency and/or large-object.
  2. You have to wrap //body// in function(){...}, which introduces wrong-this and other TCP (break/return/continue/arguments) hazards. These are real, they bite programmers too often.
# Axel Rauschmayer (14 years ago)

I see two domains for the concept of “own” properties:

  1. Meta-programming.
  2. Using objects as dictionaries.

Thanks, good to focus on use-cases. Both would like shorthand and freedom from Object.prototype.hasOwnProperty tamper-proofing.

Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts?

We don't know how dicts will fare. Making progress with for own does not interact badly with dicts if we spec them to be for-in'able -- for own (k in d) for d a dict should work, just as for objects.

Ah, shame. I had hoped that a good dictionary implementation would largely make the notion of own properties obsolete (except for #1 use cases). Bringing inheritance into the collection mix seems problematic. That’s why I like Allen’s “data-only-[]” proposal.

I agree with “not interact badly” if there are indeed other use cases.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 2:26 PM, John J Barton wrote:

On Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison <timmywillisn at gmail.com> wrote:

Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. jsperf.com/hasownproperty-vs-for-in/4#c300

Added case Object.keys().forEach:

jsperf.com/hasownproperty-vs-for-in/7

Of course results depend more on browser than form of the loop...

54 properties per object, if my skimming is accurate (is it?). Not enough to show the difference in keys allocating an array vs. some internal snapshot or iterator used by for..in.

Lots of confounding variables here. Firefox 8 wins top prize but only for the for-in loop without hasOwn guard. FF9 has type inference, so may do better still. More work on inlining should level the scores.

But this kind of performance is an ongoing arms race, and it's usually wrong to bend your coding style around particular results -- especially for small objects where the keys array allocation, and even a not-inlined function expression call, do not matter. POitRoaE.

Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study.

Finally, there ain't just one way to say it in JS. We'll have Object.keys(o).forEach(function(v,i){...}) and (in ES.next) for (i of keys(o))... or for ([k,v] of items(o))... given the module imports or a standard prelude.

# Brendan Eich (14 years ago)

On Nov 8, 2011, at 2:26 PM, John J Barton wrote:

On Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison <timmywillisn at gmail.com> wrote:

Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. jsperf.com/hasownproperty-vs-for-in/4#c300

Added case Object.keys().forEach:

jsperf.com/hasownproperty-vs-for-in/7

Also, isn't this like jsperf.com? Random people running on different machines upload results without any normalization?

Just asking, not really my point (since I think performance is only one consideration, and for non-large objects probably not significant unless "the loop" is called at high frequency).

# Andrew Paprocki (14 years ago)

On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eich <brendan at mozilla.com> wrote:

Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study.

I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the "right" way.

The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know.

# Quildreen Motta (14 years ago)

On 08/11/11 21:36, Brendan Eich wrote:

Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study.

Well, I use Object.keys, etc, a lot thorough my code. I can't remember a case where I forgot to pass the thisObject' parameter to theforEach'/`map' call in the last months, though it was weird when I transitioned to a more functional coding style.

I guess the number of cases I was bitten by the wrong |this| in the beginning is about the same number of ASI issues I ran into when I started using destructuring assignments for arrays. I'd assume that has a lot to do with coding habits — writing without properly thinking.

reduce' andreduceRight' don't have a `thisObject' argument. Why are they the only odd ones?

# Jake Verbaten (14 years ago)

On Tue, Nov 8, 2011 at 11:36 PM, Brendan Eich <brendan at mozilla.com> wrote:

Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study.

/be

I personally use Object.keys() on all my objects just because it's a neater construct. I havn't really run into much problems with the this value. None more then I would be forgetting it on any other inner function.

As an aside break and continue are emulated using Object.keys(o).any. But that is rarely done. Trying to access outer arguments or returning from inside the loop is also rare. the former is gaurded by unpacking arguments at the top of the function and the latter is gaurded by using .any again and propagating the return value. (Most of the time if I return from a loop it's a boolean)

However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5

# Quildreen Motta (14 years ago)

On 08/11/11 23:59, Jake Verbaten wrote:

However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim

Do you mean `rare' as in they have to work with the lowest common denominator (IE)? Because ES5-not-so-fully-but-somewhat-there-for-most-common-stuff environments are the majority, afaik.

# Jake Verbaten (14 years ago)

In the real world IE<9 still accounts for almost 50% of browsers. Then there's another 6% for FF3.6 and another 3% for opera.

As much as I like promoting that you should ignore legacy browsers, for most people "50% market share" is a good enough reason to support them.

# David Herman (14 years ago)

Still there, but write it out fully, to compare to the cited text:

import keys from "@iter"; for (i of keys(o)) { body }

Unless we default-import a standard prelude,

I think we should.

this is a bit much compared to add own as a modifier after for in for/in (not for/of) loops.

For for-of semantics is one of the places we've bought into a "do-over" for a JS form. It muddies the waters to say "for-of is the new for-in" but also halfway reform for-in at the same time. I don't really think

for (i of keys(o)) {
    /body/
}

is such a burden (two characters, as you say).

Instead of taking a hard-to-use-right form like for-in and partly taming it, I'd rather suggest people simply move to for-of, and have the default keys iterator Do The Right Thing and only iterate over own, enumerable property names (thanks to Yehuda and Arv for straightening us out on this point recently).

# Rick Waldron (14 years ago)

On Nov 8, 2011, at 9:08 PM, Jake Verbaten <raynos2 at gmail.com> wrote:

In the real world IE<9 still accounts for almost 50% of browsers. Then there's another 6% for FF3.6 and another 3% for opera.

Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel)

# Mark S. Miller (14 years ago)

On Tue, Nov 8, 2011 at 9:03 PM, Rick Waldron <waldron.rick at gmail.com> wrote:

Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel)

The latest externally visible Opera is Opera 12 alpha build 1116. It is indeed very close to ES5.1 compliant. But it still fails

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.3/15.3.4/15.3.4.5/S15.3.4.5_A5.js, hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch08/8.6/8.6.2/S8.6.2_A8.js, hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A5.1_T1.js

And hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch10/10.4/10.4.2/S10.4.2.1_A1.js is currently disabled because it crashes Opera 12 alpha.

The second one, S8.6.2_A8.js, is important.

# Rick Waldron (14 years ago)

On Wed, Nov 9, 2011 at 12:12 AM, Mark S. Miller <erights at google.com> wrote:

On Tue, Nov 8, 2011 at 9:03 PM, Rick Waldron <waldron.rick at gmail.com>wrote:

Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel)

The latest externally visible Opera is Opera 12 alpha build 1116. It is indeed very close to ES5.1 compliant. But it still fails

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.3/15.3.4/15.3.4.5/S15.3.4.5_A5.js

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch08/8.6/8.6.2/S8.6.2_A8.js

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A5.1_T1.js

And

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch10/10.4/10.4.2/S10.4.2.1_A1.js is currently disabled because it crashes Opera 12 alpha.

The second one, S8.6.2_A8.js, is important.

The point that I was that Opera didn't deserve to be listed among the "lost causes", but thanks for the point for point rebuttal ;)

/

# David Bruant (14 years ago)

Le 09/11/2011 02:26, Andrew Paprocki a écrit :

On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eich<brendan at mozilla.com> wrote:

Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the "right" way.

The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know.

The |this| differs between the body of a for-in and the argument callback in the .forEach. Nothing to do with Object.keys. .forEach has a second optional argument which is the value to be used as |this| so that you don't have to do a .bind.

# Xavier MONTILLET (14 years ago)

for own (i in o) { //body }

I'd rather see something like

for (i inside o) { //body }

And the reason for this is you could then use it in conditions as you use in:

if ( 'prop' in obj ) { //body }

if ( 'prop' inside obj ) { //body }

You would have 'prop' inside obj <=> Object.prototype.hasOwnProperty.call( obj, 'prop' )

# Jorge (14 years ago)

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

# Dean Landolt (14 years ago)

On Wed, Nov 9, 2011 at 3:40 PM, Jorge <jorge at jorgechamorro.com> wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

A goto? Really? Array.prototype.some is a good way to get forEach-like behavior where you can break out of.

# Brendan Eich (14 years ago)

On Nov 9, 2011, at 12:40 PM, Jorge wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

"goto" as in C, from body to a label in the outer function or script? Seriously?

You could always use try/catch/throw, but who would?

Escape continuations and call/cc are off the agenda.

See strawman:block_lambda_revival -- that's the only way you're going to get break as safer goto to work here. There: I closed on a positive note! :

# Dean Landolt (14 years ago)

On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 9, 2011, at 12:40 PM, Jorge wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

"goto" as in C, from body to a label in the outer function or script? Seriously?

You could always use try/catch/throw, but who would?

Umm, es-next, right? In a way, isn't this what StopIteration is? :)

Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can. And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

# Brendan Eich (14 years ago)

On Nov 9, 2011, at 1:15 PM, Dean Landolt wrote:

On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich <brendan at mozilla.com> wrote: On Nov 9, 2011, at 12:40 PM, Jorge wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

"goto" as in C, from body to a label in the outer function or script? Seriously?

You could always use try/catch/throw, but who would?

Umm, es-next, right? In a way, isn't this what StopIteration is? :)

No, that's almost entirely under the for/of hood. The number of users who have to manually catch in order to write schedulers is miniscule compared to the population who'll write loops, comprehensios, and generator expressions.

Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can.

Yes.

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot).

# Quildreen Motta (14 years ago)

On 09/11/11 19:20, Brendan Eich wrote:

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot).

That sounds like something to look forward to. Though, did TC39 reach a consensus on having or not block-lambdas or just a shorter function syntax?

# Dean Landolt (14 years ago)

On Wed, Nov 9, 2011 at 4:20 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 9, 2011, at 1:15 PM, Dean Landolt wrote:

On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Nov 9, 2011, at 12:40 PM, Jorge wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

"goto" as in C, from body to a label in the outer function or script? Seriously?

You could always use try/catch/throw, but who would?

Umm, es-next, right? In a way, isn't this what StopIteration is? :)

No, that's almost entirely under the for/of hood. The number of users who have to manually catch in order to write schedulers is miniscule compared to the population who'll write loops, comprehensios, and generator expressions.

Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can.

Yes.

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys.

Aye, but I suspect that's because many people don't realize that some is a superset of forEach, and IIUC is for exactly this use case. I bet this lack of awareness of the rest of the array extras will be improved with time -- I don't think it lends much support to any argument for fancy new control flow semantics.

With block-lambdas they could have their cake and break from it too

That's what I'm afraid of :-/

(and the call would be paren-free to boot).

# David Herman (14 years ago)

On Nov 9, 2011, at 1:33 PM, Quildreen Motta wrote:

On 09/11/11 19:20, Brendan Eich wrote:

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot).

That sounds like something to look forward to.

I agree! :)

Though, did TC39 reach a consensus on having or not block-lambdas or just a shorter function syntax?

It's still a topic of discussion, not on the ES6 plate but ongoing work.

# Brendan Eich (14 years ago)

On Nov 9, 2011, at 1:33 PM, Dean Landolt wrote:

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys.

Aye, but I suspect that's because many people don't realize that some is a superset of forEach, and IIUC is for exactly this use case. I bet this lack of awareness of the rest of the array extras will be improved with time -- I don't think it lends much support to any argument for fancy new control flow semantics.

Agreed, and I'm not the one making that argument! No goto, no block-lambda for only this case.

The main argument for block-lambdas is shorter function syntax with value-added semantics. Some disagree on the "-added".

# Axel Rauschmayer (14 years ago)

And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job.

Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot).

+1

Do block-lamdbas count as a fix for the dynamic this problem? Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the this of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects this to have a value.

# Brendan Eich (14 years ago)

On Nov 9, 2011, at 2:43 PM, Axel Rauschmayer wrote:

Do block-lamdbas count as a fix for the dynamic this problem?

Definitely.

Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the this of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects this to have a value.

No, if you call such functions via object.method() references then this binds to object. You can't break such compatibility only at runtime, and only some of the time.

# Andy Earnshaw (14 years ago)

Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for':

for own (i in o) {

body

}

This is a small thing but it might pay off in the long run.

I was thinking of raising a similar suggestion, but I wasn't sure when to jump in and bring it up. However, I think it could be more useful to introduce another operator like in as syntactic sugar for hasOwnProperty and have it work in a for loop similar to how for...in works too.

/* Desugared property check -> */ o.hasOwnProperty(prop)

/* Sweetened property check -> */ prop on o

/* Desugared loop -> */ for (i in o) { if o.hasOwnProperty(i) { ... }

/* Sweetened loop -> */ for (i on o) { ... }

I could see it being useful as an operator in situations where you might have an object map:

var obj = { key1: val1, key2: val2 }

if ("key1" on obj) {

 // ...

}

I think Dr Rauschmayer mentioned Python's on and I think it fits in here quite nicely. in for anywhere in the chain, on for direct properties. If it's a little too close for comfort, you could stick with own or reverse the operands and call it hasown. Perhaps that would seem too inconsistent, though. Overall, I think it's a great idea. It's fairly common for developers to forget to do a hasOwnProperty check when enumerating. As for Object.keys(o).forEach(), the speed just doesn't compare and it doesn't look too great.

Andy Earnshaw

# Jorge (14 years ago)

On 09/11/2011, at 22:05, Brendan Eich wrote:

On Nov 9, 2011, at 12:40 PM, Jorge wrote:

On 08/11/2011, at 22:17, John J Barton wrote:

Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body });

By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ?

"goto" as in C, from body to a label in the outer function or script? Seriously?

OMG. Did I say that ? a goto across functions ? :-P My bad.