Enumerability

2014-01-09 Thread Axel Rauschmayer
I’m still really unhappy about enumerability in ECMAScript. I find it 
frustratingly inconsistent:

* At the moment, only Object.keys and the for-in loop are affected by it.
* In ECMAScript 6, Object.assign will also ignore non-enumerable properties.
* Built-in prototype methods are non-enumerable, as is property `length` of 
arrays.
* In ECMAScript 6, prototype methods created by classes are enumerable, the 
prototype method `constructor` is non-enumerable (as it is by default in all 
functions).

I’ve seen various explanations for what enumerability is:

1. Something that won’t matter in the long run. But then why are we introducing 
new constructs that take it into consideration?
2. Something that one has to do properly so that old code doesn’t break. Here, 
it’d be helpful to be concrete: where can this happen? The obvious case is 
for-in for instances of built-in constructors.
3. Signaling an intent of sharing. But what does that mean in practice? Why are 
built-in methods different from user-defined methods in this regard?
4. A way of marking a method as private. Again: why the divergence between 
built-in methods and user-defined methods?

I think it would really help the design of ECMAScript going forward if we had a 
definitive and complete explanation of what enumerability is now and what it 
should be in the future. I’m trying to make sense of it and to explain it to 
others and continue to fail.

Axel

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Andreas Rossberg
On 8 January 2014 17:32, Mark S. Miller erig...@google.com wrote:
 On Wed, Jan 8, 2014 at 2:33 AM, Andreas Rossberg rossb...@google.com
 wrote:
 On 7 January 2014 20:44, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
  Unless we can identify real implementation issues, the semantics of
 do { }
 
  should simply be those of a blocks.

 I don't think this flies anyway. It has to be more like a function
 body, otherwise var and function declarations would hoist out of it,
 which would be insane IMO.

 strict function declarations don't hoist out of blocks, so the hoisting
 issue is var only.

Good point.

 I would find it surprising if var declarations did not
 hoist out of do expressions.

Interesting. I have the exact opposite expectation. And I don't see
what good it would do usability-wise.


 What I'm arguing for, then, simply is to make it as much like a
 function body as possible. (That also matches the current IIFE
 practice best.)

 Also, I really would want to avoid examples like

   return do { break; }

 and similar craze.

 Is there a convincing example where cross-expression jumps would
 actually be useful?


 If all we want is sugar for IIFEs, I wouldn't bother. With arrow functions,
 IIFEs are already a lot shorter. The extra brevity of do expressions is not
 worth it.

It's not only the brevity as such, but having a natural, targeted
language feature. IIFEs are merely an encoding, and as such a
distraction. Like A + -B is brief enough, but I'm sure you prefer
saying A - B.


 What would make do expressions worthy of consideration is if they repaired
 the TCP violations of strict arrow IIFEs, including var, arguments, break,
 continue, return, and especially yield.

Can you clarify what you mean by repair? I hope you don't suggest
that while (true) { (() = do { break })() } should magically work.

I may warm up to the extra complexity more easily if somebody could
present at least some compelling use cases. :)

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Andreas Rossberg
On 8 January 2014 18:04, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 You should be able to put a 'do' in front of any BlockStatement and turn it 
 into an ExpressionStatement.

 I don't think we should have a new expression level scoping construct that 
 doesn't have the exact semantics of a Block.

Except for blocks where the cute function declaration legacy rules
from the Appendix apply, I suppose.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Kevin Smith


 I may warm up to the extra complexity more easily if somebody could
 present at least some compelling use cases. :)


Mark's mention of yield got me thinking about await expressions.  Hopefully
I'm using this correctly:

// stat is null or a Stat object
const stat = do { try { await FS.stat(path) } catch (x) { null } }

Does that work as a use case for block semantics?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Mark S. Miller
On Thu, Jan 9, 2014 at 6:18 AM, Andreas Rossberg rossb...@google.comwrote:

 On 8 January 2014 17:32, Mark S. Miller erig...@google.com wrote:
  On Wed, Jan 8, 2014 at 2:33 AM, Andreas Rossberg rossb...@google.com
  wrote:
  On 7 January 2014 20:44, Allen Wirfs-Brock al...@wirfs-brock.com
 wrote:
   Unless we can identify real implementation issues, the semantics of
  do { }
  
   should simply be those of a blocks.
 
  I don't think this flies anyway. It has to be more like a function
  body, otherwise var and function declarations would hoist out of it,
  which would be insane IMO.
 
  strict function declarations don't hoist out of blocks, so the hoisting
  issue is var only.

 Good point.

  I would find it surprising if var declarations did not
  hoist out of do expressions.

 Interesting. I have the exact opposite expectation. And I don't see
 what good it would do usability-wise.


Now that we have const and let, vars serve no usability purpose whatsoever.
However, given their existence in the language, the best we can do with
them usability-wise is to follow the principle of least surprise. Since we
have opposite surprise reactions, this doesn't tell us what to do, but at
least we should be able to agree on this criterion.



  What I'm arguing for, then, simply is to make it as much like a
  function body as possible. (That also matches the current IIFE
  practice best.)
 
  Also, I really would want to avoid examples like
 
return do { break; }
 
  and similar craze.
 
  Is there a convincing example where cross-expression jumps would
  actually be useful?
 
 
  If all we want is sugar for IIFEs, I wouldn't bother. With arrow
 functions,
  IIFEs are already a lot shorter. The extra brevity of do expressions is
 not
  worth it.

 It's not only the brevity as such, but having a natural, targeted
 language feature. IIFEs are merely an encoding, and as such a
 distraction. Like A + -B is brief enough, but I'm sure you prefer
 saying A - B.


In a language with infix + and unary -, *and the absence of prior
expectations of an infix -*, the pressure to add an infix minus is small
for exactly this reason. A repeated pattern often comes to be perceived as
a phrase. In the absence of infix minus or prior expectations, A + -B would
rapidly become seen to do what it does.

I do have one usability concern with arrow IIFEs. I hate when I see them
written as ()={...whatever...}() because you don't know that it's an IIFE
until the end. Function expressions have the same issue. We should adapt
Crock's recommended paren style to arrow IIFEs, to whit
(()={...whatever...}()), even though this looses a bit more brevity.




  What would make do expressions worthy of consideration is if they
 repaired
  the TCP violations of strict arrow IIFEs, including var, arguments,
 break,
  continue, return, and especially yield.

 Can you clarify what you mean by repair? I hope you don't suggest
 that while (true) { (() = do { break })() } should magically work.


No, I am not suggesting that code within the do block is TCP wrt the
context outside the function containing the do expression. This would be a
TCP violation wrt the context of the do expression. Rather, I suggest that
the following must work:

while (true) { do { break; } }




 I may warm up to the extra complexity more easily if somebody could
 present at least some compelling use cases. :)

 /Andreas




-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Kevin Smith


 I do have one usability concern with arrow IIFEs. I hate when I see them
 written as ()={...whatever...}() because you don't know that it's an IIFE
 until the end. Function expressions have the same issue. We should adapt
 Crock's recommended paren style to arrow IIFEs, to whit
 (()={...whatever...}()), even though this looses a bit more brevity.


I believe this is required by the grammar anyway.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2014-01-09 Thread Allen Wirfs-Brock

On Jan 9, 2014, at 6:21 AM, Andreas Rossberg wrote:

 On 8 January 2014 18:04, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 You should be able to put a 'do' in front of any BlockStatement and turn it 
 into an ExpressionStatement.
 
 I don't think we should have a new expression level scoping construct that 
 doesn't have the exact semantics of a Block.
 
 Except for blocks where the cute function declaration legacy rules
 from the Appendix apply, I suppose.

Right.  No legacy issues with do {}.

And those ugly legacy rules only apply in limited circumstances...

Allen

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss