Re: Additional Math functions

2015-04-29 Thread Caitlin Potter
Just a note about the whole upper bounds on arguments thing

In V8’s case (per the comment regarding io.js), the maximum arguments count for 
Function.prototype.apply/Reflect.apply/Reflect.construct is 0x80 
(https://github.com/v8/v8-git-mirror/blob/81345f1a2cdceaee8c891fc7512ae671f171308e/src/macros.py#L75
 
)
 — On a 64mb system, this ends up being close to 70mb of data which the engine 
pushes to the stack, in addition to being on the heap in the array itself — 
which is not super tiny, but a desktop machine can probably handle a lot more. 
This isn’t a “real” stack overflow, because the RangeError is thrown before any 
arguments are actually pushed to the stack — it’s just an upper bound on the 
size of the array which can be pushed. SpiderMonkey has a similar arbitrary 
upper bounds on the argument length, ARGS_LENGTH_MAX 
(https://github.com/mozilla/gecko-dev/blob/d03ee825c74355f070b14cf4325897c813373902/js/src/vm/ArgumentsObject.h#L77
 
)
 or 0x7A120, which is a much more conservative limit. Apparently nobody has 
complained about the smaller limit, so that’s something =)

I guess what this means is, people aren’t generally depending on being able to 
push zillions of arguments to the stack via fn.apply — it’s almost always one 
of two things: either a small-ish array literal, or an actual Arguments object, 
which most likely doesn’t contain zillions of arguments either. These limits 
don’t seem unreasonable, and it’s probably okay to figure out an appropriate 
limit (especially for mobile devices) that still makes developers happy.

> On Apr 29, 2015, at 8:28 PM, Brendan Eich  wrote:
> 
> C. Scott Ananian wrote:
>> I'm just saying: it's not safe to spread an arbitrary array into `arguments` 
>> unless the spec explicitly says that the number of arguments is limited only 
>> by heap size (not stack size) or something like that.  The ES6 spec does not 
>> contain any such language.
> 
> We've talked about this in past meetings. We want implementations and 
> developers to cooperate and compete, to find a normative spec we can back. It 
> would be silly for us to "pick a number".
> 
> /be
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

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


Re: Additional Math functions

2015-04-29 Thread Brendan Eich

C. Scott Ananian wrote:
I'm just saying: it's not safe to spread an arbitrary array into 
`arguments` unless the spec explicitly says that the number of 
arguments is limited only by heap size (not stack size) or something 
like that.  The ES6 spec does not contain any such language.


We've talked about this in past meetings. We want implementations and 
developers to cooperate and compete, to find a normative spec we can 
back. It would be silly for us to "pick a number".


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


Re: is an iterator allowed to reuse the same "state" object?

2015-04-29 Thread Andreas Rossberg
On 29 April 2015 at 18:37, Brendan Eich  wrote:

> Andreas Rossberg wrote:
>
>> On 29 April 2015 at 02:21, John Lenz > concavel...@gmail.com>> wrote:
>>
>> I missed it, thanks.I know things will improve in time but I'm
>> just coming from a discussion with folks complaining about the
>> performance of generators and GC overhead in real code with Chrome
>> and Firefox relative to simple hand written loops.
>>
>>
>> Note that there is a huge difference between optimising iterators (in
>> particular, for-of), and optimising generators. I expect that VMs will
>> start getting better on the former relatively soon, for iterators that are
>> not generators. Making generators fast is a much more complicated problem.
>>
>
> But in either case, escape analysis and object allocation elimination can
> avoid the flood of eden objects John cited, right?
>

Yes, together with inlining.

I'm inferring your comment about generator optimization hardship has to do
> with a function that yields -- whose CFG has multiple entry points and
> whose activation record must live in the heap.


Yes, the biggest challenge perhaps is not even generator CFGs per se, but
getting inlining to work with them, which is necessary to take advantage of
escape analysis.

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 2:36 PM, C. Scott Ananian wrote:

> On Wed, Apr 29, 2015 at 4:16 PM, Allen Wirfs-Brock  
> wrote:
> On Apr 29, 2015, at 12:40 PM, C. Scott Ananian wrote:
>> On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock  
>> wrote:
>> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>>> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock  
>>> wrote:
>>>  class DefensivePromise extends Promise {
>>>   constructor(x) {
>>> super(x);
>>> if (new.target === DefensivePromise) {
>>>// I'm assuming this test is just to be subclass friendly and 
>>> allow subclasses to freeze later? 
>>>   Object.freeze(this);
>>> }
>>>   }
>>>   static resolve(x) {
>>> switch (true) {
>>>default:
>>>  // I guess a do { } while(false); would work as well? 
>>>   // assuming frozen primordial
>>>   if (x.constructor !== DefensivePromise) break;  //just a quick 
>>> exit, doesn't guarantee much
>>>   if (!Object.isFrozen(x)) break;
>>>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>>   //a more subclass friendly approach would walk x's [[Prototype]] 
>>> chain to ensure that the correct 'then' is inherited from frozen prototypes
>>>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype) 
>>> break;
>>>   //Assert: x.then === Promise.prototype.then, now and forever after
>>>   return x;
>>>  }
>>>  // must be called on a subclass of DefensivePromise, so we don't need 
>>> to enforce the 'then' invariant 
>>>  If  (x.constructor ===  this) return x;   //in which case a 
>>> constructor check is good enough
>>>   // ^^ this is a mistake right?  I think this line doesn't belong. 
>>>  return new this(r => {r(x)});
>>>}
>>>  }
>>> Object.freeze(DefensivePromise);
>>> Object.freeze(DefensivePromise.prototype);
>>> 
>>> It's not clear what the `x.constructor` test is still doing in your 
>>> implementation.
>> 
>> Do you mean the first or second occurrence?
>> 
>> The second occurrence.  At that point all we know about x is that it's *not* 
>> something safe.  We shouldn't be looking at `constructor` in that case.
> 
> the last two lines of the above `resolve` method should be replaced with:
>  return super.resolve(x)
> 
> x.construct === this is the test that I propose Promise.resolve should make 
> instead of  testing [[PromiseConstructor]]
> There should probably also be another test that SpeciesConstrutor(x)===this 
> 
> This is still not correct.
> 
> You can't call `super.resolve(x)` safely unless you know that 
> this.constructor is trustworthy.  If you've bailed out of the `switch`, you 
> don't know that.

you're correct.  Let's go with:

class DefensivePromise extends Promise {
  constructor(x) {
super(x);
if (new.target === DefensivePromise) {
  Object.freeze(this);
}
  }
  static resolve(x) {
if (this===DefensivePromise) {
   switch (true) {
  default:
 // assuming frozen primordial
 if (x.constructor !== DefensivePromise) break;  //just a quick 
exit, doesn't guarantee much
 if (!Object.isFrozen(x)) break;
 If (Object.getOwnPropertyDescriptor(x, 'then')) break;
 //a more subclass friendly approach would walk x's [[Prototype]] 
chain to ensure that the correct 'then' is inherited from frozen prototypes
 if (Object.getPrototypeOf(x) !== DefensivePromise.prototype) break;
 //Assert: x.then === Promise.prototype.then, now and forever after
 return x;
};
   return new this(r => {r(x)});
}
// must be called on a subclass of DefensivePromise, so we don't need to 
enforce the DefensivePromise 'then' invariant 
return super.resolve(x);
}
 }
Object.freeze(DefensivePromise);
Object.freeze(DefensivePromise.prototype);

> 
> A correct implementation just does `return new this(r => { r(x); })` after 
> the switch.
> 
> The "another test" that you propose seems to be exactly the fix which Brandon 
> proposed and I codified, to wit:
> 
> 2. If IsPromise(x) is true,
> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
> b. If SameValue(constructor, C) is true, return x.
> 

That can't right.  x could be an object that is not a C but whose 
SpeciesConstructor is C.  In that case, a new C promise on x still has to be 
created.  But your code would just return x.  I would use a 'construtor' test 
in step 2. But if 'constructor' is not C and SpeciesConstructor is also not C 
then an extra level of C wrapping is needed.



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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Brendan Eich

Allen Wirfs-Brock wrote:
But the specified [[PromiseConstructor]] test doesn't  really hurt 
anything.


I've heard that before!

It's a wart implementations can avoid shipping, to avoid Murphy's-Law 
compatibility constraints growing on top of it. You don't want a wart at 
all, certainly not with ugly MLcc atop it! :-|


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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Brendan Eich

Allen Wirfs-Brock wrote:
Regardless, too late for ES2015.  It will have to proposed as an 
ES2016 change.


Could we errata quickly? Implementations should not ship the bug.

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 2:44 PM, Mark S. Miller wrote:

> On Wed, Apr 29, 2015 at 2:36 PM, C. Scott Ananian  
> wrote:
> [...]
> Mark, after you've slept on this and assuming you haven't changed your mind, 
> would you be willing to be the TC39 champion?  I'm not a participant in that 
> process.
> 
> Yes.

probably need to make sure that Domenic is in the loop.

Allen

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
On Wed, Apr 29, 2015 at 2:36 PM, C. Scott Ananian 
wrote:
[...]

> Mark, after you've slept on this and assuming you haven't changed your
> mind, would you be willing to be the TC39 champion?  I'm not a participant
> in that process.
>

Yes.

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 4:16 PM, Allen Wirfs-Brock 
wrote:

> On Apr 29, 2015, at 12:40 PM, C. Scott Ananian wrote:
>
> On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock 
> wrote:
>
>> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>>
>> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock > > wrote:
>>
>>>  class DefensivePromise extends Promise {
>>>   constructor(x) {
>>> super(x);
>>> if (new.target === DefensivePromise) {
>>>
>>// I'm assuming this test is just to be subclass friendly and
>> allow subclasses to freeze later?
>>
>>>   Object.freeze(this);
>>> }
>>>   }
>>>   static resolve(x) {
>>> switch (true) {
>>>default:
>>>
>>  // I guess a do { } while(false); would work as well?
>>
>>>   // assuming frozen primordial
>>>   if (x.constructor !== DefensivePromise) break;  //just a quick
>>> exit, doesn't guarantee much
>>>   if (!Object.isFrozen(x)) break;
>>>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>>   //a more subclass friendly approach would walk x's
>>> [[Prototype]] chain to ensure that the correct 'then' is inherited from
>>> frozen prototypes
>>>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype)
>>> break;
>>>   //Assert: x.then === Promise.prototype.then, now and forever
>>> after
>>>   return x;
>>>  }
>>>  // must be called on a subclass of DefensivePromise, so we don't
>>> need to enforce the 'then' invariant
>>>  If  (x.constructor ===  this) return x;   //in which case a
>>> constructor check is good enough
>>>
>>   // ^^ this is a mistake right?  I think this line doesn't
>> belong.
>>
>>>  return new this(r => {r(x)});
>>>}
>>>  }
>>> Object.freeze(DefensivePromise);
>>> Object.freeze(DefensivePromise.prototype);
>>>
>>
>> It's not clear what the `x.constructor` test is still doing in your
>> implementation.
>>
>>
>> Do you mean the first or second occurrence?
>>
>
> The second occurrence.  At that point all we know about x is that it's
> *not* something safe.  We shouldn't be looking at `constructor` in that
> case.
>
>
> the last two lines of the above `resolve` method should be replaced with:
>  return super.resolve(x)
>
> x.construct === this is the test that I propose Promise.resolve should
> make instead of  testing [[PromiseConstructor]]
> There should probably also be another test that
> SpeciesConstrutor(x)===this
>

This is still not correct.

You can't call `super.resolve(x)` safely unless you know that
this.constructor is trustworthy.  If you've bailed out of the `switch`, you
don't know that.

A correct implementation just does `return new this(r => { r(x); })` after
the switch.

The "another test" that you propose seems to be exactly the fix which
Brandon proposed and I codified, to wit:

2. If IsPromise(x) is true,
> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
> b. If SameValue(constructor, C) is true, return x.


I wouldn't jump the gun until we actually have TC39 consensus on a proposal.
>

Mark, after you've slept on this and assuming you haven't changed your
mind, would you be willing to be the TC39 champion?  I'm not a participant
in that process.


> What we've shown is that the [[PromiseConstructor]] test was never
> sufficient to guarantee the invariant that Mark is concerned about and also
> that there probably isn't a generic check we can do that would satisfy his
> requirements.  He has do it himself like shown above.  But the specified
> [[PromiseConstructor]] test doesn't  really hurt anything.  It places some
> slight limitations on what subclasses can do, but probably doesn't
> interfere with anything an actual subclass is likely to do.  It seems like
> a restriction than can be relaxed in the future without anybody (or than
> conformance tests) noticing.
>

Well, the [[PromiseConstructor]] test is breaking `prfun`, `es6-shim` and
`core-js` right now, which is why I noticed it in the first place.  (v8
seems to have implemented the `[[PromiseConstructor]]` internal property
even though they don't have `new.target` implemented, so it's always
hard-wired to `Promise`.)  And `babel` and `core-js` have implemented
non-standard semantics for `Promise.resolve` as a result.

In particular, with the current state of `Promise.resolve`, I can't
subclass `Promise` in a meaningful way using ES5 syntax (see, the thread
title turns relevant again!).  So I have a vested interest in getting the
semantics fixed so that people can start using `Promise` subclasses (like
`prfun` does) instead of writing their "extra" Promise helpers directly on
the `Promise` global object, while we're all waiting for ES6 syntax to make
it to the mainstream.

(And when I say "getting the semantics fixed" what I really mean is
"consensus among TC39" so that shim libraries can implement the correct
semantics as early adopters, with assurance the browser engines will
follow.)

Since 

Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 12:40 PM, C. Scott Ananian wrote:

> On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock  
> wrote:
> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock  
>> wrote:
>>  class DefensivePromise extends Promise {
>>   constructor(x) {
>> super(x);
>> if (new.target === DefensivePromise) {
>>// I'm assuming this test is just to be subclass friendly and 
>> allow subclasses to freeze later? 
>>   Object.freeze(this);
>> }
>>   }
>>   static resolve(x) {
>> switch (true) {
>>default:
>>  // I guess a do { } while(false); would work as well? 
>>   // assuming frozen primordial
>>   if (x.constructor !== DefensivePromise) break;  //just a quick 
>> exit, doesn't guarantee much
>>   if (!Object.isFrozen(x)) break;
>>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>   //a more subclass friendly approach would walk x's [[Prototype]] 
>> chain to ensure that the correct 'then' is inherited from frozen prototypes
>>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype) break;
>>   //Assert: x.then === Promise.prototype.then, now and forever after
>>   return x;
>>  }
>>  // must be called on a subclass of DefensivePromise, so we don't need 
>> to enforce the 'then' invariant 
>>  If  (x.constructor ===  this) return x;   //in which case a constructor 
>> check is good enough
>>   // ^^ this is a mistake right?  I think this line doesn't belong. 
>>  return new this(r => {r(x)});
>>}
>>  }
>> Object.freeze(DefensivePromise);
>> Object.freeze(DefensivePromise.prototype);
>> 
>> It's not clear what the `x.constructor` test is still doing in your 
>> implementation.
> 
> Do you mean the first or second occurrence?
> 
> The second occurrence.  At that point all we know about x is that it's *not* 
> something safe.  We shouldn't be looking at `constructor` in that case.

the last two lines of the above `resolve` method should be replaced with:
 return super.resolve(x)

x.construct === this is the test that I propose Promise.resolve should make 
instead of  testing [[PromiseConstructor]]
There should probably also be another test that SpeciesConstrutor(x)===this 

>  
>> But, regardless of the details of our implementations, can we agree that 
>> "tamper proof" promises don't seem to need the [[PromiseConstructor]] 
>> property?
> 
> I agree with you, but I'm not the Promise champion.
> 
> Regardless, too late for ES2015.  It will have to proposed as an ES2016 
> change.
> 
> True, but since subclassable Promises haven't been implemented in the major 
> engines yet, still in time to get everyone to agree to implement the new 
> semantics before use "in the wild" locks in the warts of ES2015.
> 
> If we get consensus, I can certainly ensure that es6-shim, core-js, and babel 
> implement the "ES2016" semantics.

I wouldn't jump the gun until we actually have TC39 consensus on a proposal.

What we've shown is that the [[PromiseConstructor]] test was never sufficient 
to guarantee the invariant that Mark is concerned about and also that there 
probably isn't a generic check we can do that would satisfy his requirements.  
He has do it himself like shown above.  But the specified 
[[PromiseConstructor]] test doesn't  really hurt anything.  It places some 
slight limitations on what subclasses can do, but probably doesn't interfere 
with anything an actual subclass is likely to do.  It seems like a restriction 
than can be relaxed in the future without anybody (or than conformance tests) 
noticing.

Allen

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
On Wed, Apr 29, 2015 at 12:40 PM, C. Scott Ananian 
wrote:

> On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock 
> wrote:
>
>> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>>
>> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock > > wrote:
>>
>>>  class DefensivePromise extends Promise {
>>>   constructor(x) {
>>> super(x);
>>> if (new.target === DefensivePromise) {
>>>
>>// I'm assuming this test is just to be subclass friendly and
>> allow subclasses to freeze later?
>>
>>>   Object.freeze(this);
>>> }
>>>   }
>>>   static resolve(x) {
>>> switch (true) {
>>>default:
>>>
>>  // I guess a do { } while(false); would work as well?
>>
>>>   // assuming frozen primordial
>>>   if (x.constructor !== DefensivePromise) break;  //just a quick
>>> exit, doesn't guarantee much
>>>   if (!Object.isFrozen(x)) break;
>>>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>>   //a more subclass friendly approach would walk x's
>>> [[Prototype]] chain to ensure that the correct 'then' is inherited from
>>> frozen prototypes
>>>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype)
>>> break;
>>>   //Assert: x.then === Promise.prototype.then, now and forever
>>> after
>>>   return x;
>>>  }
>>>  // must be called on a subclass of DefensivePromise, so we don't
>>> need to enforce the 'then' invariant
>>>  If  (x.constructor ===  this) return x;   //in which case a
>>> constructor check is good enough
>>>
>>   // ^^ this is a mistake right?  I think this line doesn't
>> belong.
>>
>>>  return new this(r => {r(x)});
>>>}
>>>  }
>>> Object.freeze(DefensivePromise);
>>> Object.freeze(DefensivePromise.prototype);
>>>
>>
>> It's not clear what the `x.constructor` test is still doing in your
>> implementation.
>>
>>
>> Do you mean the first or second occurrence?
>>
>
> The second occurrence.  At that point all we know about x is that it's
> *not* something safe.  We shouldn't be looking at `constructor` in that
> case.
>
>
>> But, regardless of the details of our implementations, can we agree that
>> "tamper proof" promises don't seem to need the [[PromiseConstructor]]
>> property?
>>
>>
>> I agree with you, but I'm not the Promise champion.
>>
>> Regardless, too late for ES2015.  It will have to proposed as an ES2016
>> change.
>>
>
> True, but since subclassable Promises haven't been implemented in the
> major engines yet, still in time to get everyone to agree to implement the
> new semantics before use "in the wild" locks in the warts of ES2015.
>
> If we get consensus,
>


I want to sleep on it, but at the moment I am convinced. Thanks for pushing
on this!




> I can certainly ensure that es6-shim, core-js, and babel implement the
> "ES2016" semantics.
>   --scott
>

Excellent.


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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock 
wrote:

> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>
> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock 
> wrote:
>
>>  class DefensivePromise extends Promise {
>>   constructor(x) {
>> super(x);
>> if (new.target === DefensivePromise) {
>>
>// I'm assuming this test is just to be subclass friendly and
> allow subclasses to freeze later?
>
>>   Object.freeze(this);
>> }
>>   }
>>   static resolve(x) {
>> switch (true) {
>>default:
>>
>  // I guess a do { } while(false); would work as well?
>
>>   // assuming frozen primordial
>>   if (x.constructor !== DefensivePromise) break;  //just a quick
>> exit, doesn't guarantee much
>>   if (!Object.isFrozen(x)) break;
>>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>   //a more subclass friendly approach would walk x's
>> [[Prototype]] chain to ensure that the correct 'then' is inherited from
>> frozen prototypes
>>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype)
>> break;
>>   //Assert: x.then === Promise.prototype.then, now and forever
>> after
>>   return x;
>>  }
>>  // must be called on a subclass of DefensivePromise, so we don't
>> need to enforce the 'then' invariant
>>  If  (x.constructor ===  this) return x;   //in which case a
>> constructor check is good enough
>>
>   // ^^ this is a mistake right?  I think this line doesn't
> belong.
>
>>  return new this(r => {r(x)});
>>}
>>  }
>> Object.freeze(DefensivePromise);
>> Object.freeze(DefensivePromise.prototype);
>>
>
> It's not clear what the `x.constructor` test is still doing in your
> implementation.
>
>
> Do you mean the first or second occurrence?
>

The second occurrence.  At that point all we know about x is that it's
*not* something safe.  We shouldn't be looking at `constructor` in that
case.


> But, regardless of the details of our implementations, can we agree that
> "tamper proof" promises don't seem to need the [[PromiseConstructor]]
> property?
>
>
> I agree with you, but I'm not the Promise champion.
>
> Regardless, too late for ES2015.  It will have to proposed as an ES2016
> change.
>

True, but since subclassable Promises haven't been implemented in the major
engines yet, still in time to get everyone to agree to implement the new
semantics before use "in the wild" locks in the warts of ES2015.

If we get consensus, I can certainly ensure that es6-shim, core-js, and
babel implement the "ES2016" semantics.
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:

> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock  
> wrote:
>  class DefensivePromise extends Promise {
>   constructor(x) {
> super(x);
> if (new.target === DefensivePromise) {
>// I'm assuming this test is just to be subclass friendly and 
> allow subclasses to freeze later? 
>   Object.freeze(this);
> }
>   }
>   static resolve(x) {
> switch (true) {
>default:
>  // I guess a do { } while(false); would work as well? 
>   // assuming frozen primordial
>   if (x.constructor !== DefensivePromise) break;  //just a quick 
> exit, doesn't guarantee much
>   if (!Object.isFrozen(x)) break;
>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>   //a more subclass friendly approach would walk x's [[Prototype]] 
> chain to ensure that the correct 'then' is inherited from frozen prototypes
>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype) break;
>   //Assert: x.then === Promise.prototype.then, now and forever after
>   return x;
>  }
>  // must be called on a subclass of DefensivePromise, so we don't need to 
> enforce the 'then' invariant 
>  If  (x.constructor ===  this) return x;   //in which case a constructor 
> check is good enough
>   // ^^ this is a mistake right?  I think this line doesn't belong. 
>  return new this(r => {r(x)});
>}
>  }
> Object.freeze(DefensivePromise);
> Object.freeze(DefensivePromise.prototype);
> 
> It's not clear what the `x.constructor` test is still doing in your 
> implementation.

Do you mean the first or second occurrence?

> 
> But, regardless of the details of our implementations, can we agree that 
> "tamper proof" promises don't seem to need the [[PromiseConstructor]] 
> property?

I agree with you, but I'm not the Promise champion.

Regardless, too late for ES2015.  It will have to proposed as an ES2016 change.

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock 
wrote:

>  class DefensivePromise extends Promise {
>   constructor(x) {
> super(x);
> if (new.target === DefensivePromise) {
>
   // I'm assuming this test is just to be subclass friendly and
allow subclasses to freeze later?

>   Object.freeze(this);
> }
>   }
>   static resolve(x) {
> switch (true) {
>default:
>
 // I guess a do { } while(false); would work as well?

>   // assuming frozen primordial
>   if (x.constructor !== DefensivePromise) break;  //just a quick
> exit, doesn't guarantee much
>   if (!Object.isFrozen(x)) break;
>   If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>   //a more subclass friendly approach would walk x's [[Prototype]]
> chain to ensure that the correct 'then' is inherited from frozen prototypes
>   if (Object.getPrototypeOf(x) !== DefensivePromise.prototype)
> break;
>   //Assert: x.then === Promise.prototype.then, now and forever
> after
>   return x;
>  }
>  // must be called on a subclass of DefensivePromise, so we don't need
> to enforce the 'then' invariant
>  If  (x.constructor ===  this) return x;   //in which case a
> constructor check is good enough
>
  // ^^ this is a mistake right?  I think this line doesn't belong.

>  return new this(r => {r(x)});
>}
>  }
> Object.freeze(DefensivePromise);
> Object.freeze(DefensivePromise.prototype);
>

It's not clear what the `x.constructor` test is still doing in your
implementation.

But, regardless of the details of our implementations, can we agree that
"tamper proof" promises don't seem to need the [[PromiseConstructor]]
property?
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


==

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 11:12 AM, C. Scott Ananian wrote:
> 
> Since it's `Promise.then` you care about, I think the approach in my previous 
> message (where `then` is tested directly) is preferable.

I agree.  If what you specifically care about is the `then` behavior you should 
be checking for a known good `then` method rather than something you think 
implies that `then` will be good.  It's exploitable errors in the implication 
logic are the source of the problem.

 class DefensivePromise extends Promise {
  constructor(x) {
super(x);
if (new.target === DefensivePromise) {
  Object.freeze(this);
}
  }
  static resolve(x) {
switch (true) {
   default:
  // assuming frozen primordial
  if (x.constructor !== DefensivePromise) break;  //just a quick exit, 
doesn't guarantee much
  if (!Object.isFrozen(x)) break;
  If (Object.getOwnPropertyDescriptor(x, 'then')) break;
  //a more subclass friendly approach would walk x's [[Prototype]] 
chain to ensure that the correct 'then' is inherited from frozen prototypes
  if (Object.getPrototypeOf(x) !== DefensivePromise.prototype) break;
  //Assert: x.then === Promise.prototype.then, now and forever after
  return x;
 }
 // must be called on a subclass of DefensivePromise, so we don't need to 
enforce the 'then' invariant 
 If  (x.constructor ===  this) return x;   //in which case a constructor 
check is good enough
 return new this(r => {r(x)});
   }
 }
Object.freeze(DefensivePromise);
Object.freeze(DefensivePromise.prototype);___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
```
  constructor(x) {
super(x);
Object.defineProperties(this, { then: { value: this.then }});
Object.freeze(this);
if (this.constructor==DefensivePromise && this.then ===
DefensivePromise.prototype.then) {
  goodPromises.add(this);
}
  }
```
Getting closer, I hope!


> I also like the point implicit in your attack that I also need the
> invariant that
>
> DefensivePromise.resolve(anything).then(anycallback)
>
> should all callback at most once.
>

I believe this is already taken care of by the ES6 spec once you make it
into `NewPromiseCapability`.  At least I wrote tests for `es6-shim` once
upon a time purporting to show this.
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Kevin Smith
>
> const goodPromises = new WeakSet();
> class DefensivePromise {
>   constructor(x) {
> super(x);
> if (new.target === DefensivePromise) {
>   Object.freeze(this);
>   goodPromises.add(this);
> }
>   }
>   static resolve(x) {
> if (goodPromises.has(x)) {
>   return x;  // should be equiv to super.resolve(x);
> }
> return new DefensivePromise(r => {r(x)});
>   }
> }
>
>
Basically you can't rely on new.target to mean what you think it means, in
the face of Reflect.construct.

Maybe this?

constructor(x) {
super(x);
// At this point you know that "this" is a Promise, but you don't
// know if the prototype is set correctly, so:
if (Object.getPrototypeOf(this) === DefensivePromise.prototype)
gooPromises.add(Object.freeze(this));
}
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
On Wed, Apr 29, 2015 at 11:12 AM, C. Scott Ananian 
wrote:

> On Wed, Apr 29, 2015 at 2:07 PM, Mark S. Miller 
> wrote:
>
>> Hi Scott, I think your approach is on the right track. How about the
>> following?
>>
>> Anyone see a way to attack it?
>>
>>
>>
>> const goodPromises = new WeakSet();
>> class DefensivePromise {
>>   constructor(x) {
>> super(x);
>> if (new.target === DefensivePromise) {
>>   Object.freeze(this);
>>   goodPromises.add(this);
>> }
>>   }
>>   static resolve(x) {
>> if (goodPromises.has(x)) {
>>   return x;  // should be equiv to super.resolve(x);
>> }
>> return new DefensivePromise(r => {r(x)});
>>   }
>> }
>>
>
> Assuming that you don't export DefensivePromise to the attacker, this is
> fine.  Otherwise, I think this is still vulnerable to Reflect.construct
> lying about new.target:
> ```
> class BadPromise extends DefensivePromise {
>   then(r) { r(); r(); }
> }
> var bp = Reflect.construct(BadPromise, DefensivePromise);
> ```
>

Clever. Yes, this attack works.



> Since it's `Promise.then` you care about, I think the approach in my
> previous message (where `then` is tested directly) is preferable.
>  --scott
>

As demonstrated, vulnerable to TOCTTOU.



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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
I do indeed need to expose DefensivePromise under the global name
"Promise", replacing the builtin. Other than itself being frozen and making
frozen promises, it should in all other ways conform exactly to the promise
spec while still guaranteeing this invariant.




> ```
>   constructor(x) {
> super(x);
> Object.freeze(this);
> if (this.constructor==DefensivePromise && this.then ===
> DefensivePromise.prototype.then && /*) {
>   goodPromises.add(this);
> }
>   }
> ```
> You probably need to make the test a little bit more careful, in case
> `then` is a malicious getter or something like that.
>

Attack:


class BadPromise {}

BadPromise.prototype.constructor = DefensivePromise;

const bp = Reflect.construct(DefensivePromise, [], BadPromise);

// Passed your checks, and so bp is frozen and added to goodPromises.
// But IIUC bp.[[Prototype]] is BadPromise.prototype.

BadPromise.prototype.then = r => {r(), r()};  // borrowed from your attack.


bp is now an attack object which can be used in a plan interference attack,
by inappropriately synchronously calling r.
I also like the point implicit in your attack that I also need the
invariant that

DefensivePromise.resolve(anything).then(anycallback)

should all callback at most once.




> But my point is that you can do all this in userland, you don't need to
> expose its complexity or bake any of it into the Promise spec.
>  --scott
>


I suspect you are correct. But let's reserve judgement until you, I, or
someone succeeds at writing userland code immune to attack.


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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 2:07 PM, Mark S. Miller  wrote:

> Hi Scott, I think your approach is on the right track. How about the
> following?
>
> Anyone see a way to attack it?
>
>
>
> const goodPromises = new WeakSet();
> class DefensivePromise {
>   constructor(x) {
> super(x);
> if (new.target === DefensivePromise) {
>   Object.freeze(this);
>   goodPromises.add(this);
> }
>   }
>   static resolve(x) {
> if (goodPromises.has(x)) {
>   return x;  // should be equiv to super.resolve(x);
> }
> return new DefensivePromise(r => {r(x)});
>   }
> }
>

Assuming that you don't export DefensivePromise to the attacker, this is
fine.  Otherwise, I think this is still vulnerable to Reflect.construct
lying about new.target:
```
class BadPromise extends DefensivePromise {
  then(r) { r(); r(); }
}
var bp = Reflect.construct(BadPromise, DefensivePromise);
```

Since it's `Promise.then` you care about, I think the approach in my
previous message (where `then` is tested directly) is preferable.
 --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
Hi Scott, I think your approach is on the right track. How about the
following?

Anyone see a way to attack it?



const goodPromises = new WeakSet();
class DefensivePromise {
  constructor(x) {
super(x);
if (new.target === DefensivePromise) {
  Object.freeze(this);
  goodPromises.add(this);
}
  }
  static resolve(x) {
if (goodPromises.has(x)) {
  return x;  // should be equiv to super.resolve(x);
}
return new DefensivePromise(r => {r(x)});
  }
}


Note a few typos fixed and a few simplifications, all of which you should
double check. Thanks!


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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 1:37 PM, Mark S. Miller  wrote:

> On Wed, Apr 29, 2015 at 10:26 AM, C. Scott Ananian 
> wrote:
>
>> On Wed, Apr 29, 2015 at 1:00 PM, Mark S. Miller 
>> wrote:
>>
>>> The invariant I am interested in:
>>>
>>> In a realm where we (the trusted defender who runs first) make Promise
>>> defensive as follows
>>>
>>> * Freeze everything primordial, as SES does
>>>
>>> * Make a DefensivePromise subclass of Promise that differs minimally,
>>> hopefully only by ensuring that its instances are frozen.
>>>
>>> * "Promise = DefensivePromise;" do "Promise" below refers to
>>> DefensivePromise
>>>
>>> * Freezing whitelisted global properties, as SES currently does for ES5
>>> globals, but for ES6 including "Promise"
>>>
>>>
>>> then it must be the case that
>>>
>>> Promise.resolve(anything).then(anycallback)
>>>
>>> for an anything provided by a potential attacker, when executed in the
>>> middle of a turn does not call callback during that turn. If it calls
>>> anycallback at all, it calls it back *as* a later turn, i.e., in a later
>>> turn starting from an empty stack.
>>>
>>
>> How about:
>> ```
>> var goodPromises = new WeakSet();
>> class DefensivePromise {
>>   constructor(x) {
>> super(x);
>> Object.freeze(this);
>> // check this.constructor here if you are paranoid.
>> goodPromises.add(this);
>>   }
>>   resolve(x) {
>> if (goodPromises.has(x)) {
>>   return super.resolve(x);
>> }
>> return new DefensivePromise(function(r){r(x);});
>>   }
>> }
>> ```
>> Doesn't seem like this needs special support in the Promise spec.
>>
>> Note that the `goodPromises` set won't be fooled by passing in
>> `DefensivePromise` as `new.target` to `Promise` without actually running
>> the `DefensivePromise` constructor.
>>   --scott
>>
>
> Isn't this still vulnerable to the Promise.resolve attack? IIUC, this
> attack enables the attacker to cause this.constructor to lie, so how would
> checking it help?
>

Because I only allow `DefensivePromise.resolve` to check `this.constructor`
(via the call to super.resolve) if I know that `this.constructor` is not
lying (because I froze `this.constructor` before adding it to
`goodPromises`).  All other promises get wrapped in a new
`DefensivePromise`, which should enforce the desired "not on this turn"
invariant.

In this particular example, I'm not exporting DefensivePromise, just using
it internally to sanitize "anything provided by a potential attacker"
(while preserving efficiency if the attacker is in good faith giving my
promises back to me).  If you want to export `DefensivePromise` and allow
malicious code to subclass it, then you should perform some additional
checks after freezing and before adding to `goodPromises`, perhaps
something like:
```
  constructor(x) {
super(x);
Object.freeze(this);
if (this.constructor==DefensivePromise && this.then ===
DefensivePromise.prototype.then && /*) {
  goodPromises.add(this);
}
  }
```
You probably need to make the test a little bit more careful, in case
`then` is a malicious getter or something like that.  But my point is that
you can do all this in userland, you don't need to expose its complexity or
bake any of it into the Promise spec.
 --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-binding destructuring assignment

2015-04-29 Thread Tab Atkins Jr.
On Wed, Apr 29, 2015 at 10:44 AM, Rick Waldron  wrote:
> Why "_"? A linter can just allow the end developer to define the binding
> name.
>
> https://github.com/jshint/jshint/issues/2352

Of course.  _ is just a common name for the "i don't care" destructuring slot.

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


Re: Additional Math functions

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 12:56 PM, Allen Wirfs-Brock 
wrote:

> On Apr 29, 2015, at 9:04 AM, C. Scott Ananian wrote:
> > I suppose it would be nice if JavaScript engines fell back to passing
> arguments on the heap to avoid this problem, but I don't think that's part
> of the ES6 spec.  Am I mistaken?
>
> that's an implementation detail. The ES spec. doesn't care whether or not
> you employee multiple argument passing strategies in your implementation.
> Personally, I wouldn't bother unless for some reason the implementation had
> a very small (<10?) stack based argument limit.
>
> Similar, anyone who who wants to spread a large array into an argument
> list is probably misguided.
>

I'm just saying: it's not safe to spread an arbitrary array into
`arguments` unless the spec explicitly says that the number of arguments is
limited only by heap size (not stack size) or something like that.  The ES6
spec does not contain any such language.

For tail calls, the spec says:

> A tail position call must either release any transient internal resources
> associated with the currently executing function execution context before
> invoking the target function or reuse those resources in support of the
> target function.
> NOTE For example, a tail position call should only grow an
> implementation’s activation record stack by the amount that the size of the
> target function’s activation record exceeds the size of the calling
> function’s activation record. If the target function’s activation record is
> smaller, then the total size of the stack should decrease.


I'm not sure exactly how you'd write equivalent language for "arbitrary
arguments size", something like a note on section 9.2.12
"FunctionDeclarationInstantiation" stating,
"An execution context should use resources only for named arguments of the
function.  Unnamed formals should not increase the size of the Environment
Record."
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Additional Math functions

2015-04-29 Thread Sander Deryckere
@Allen: I guess that cloning the array into the arguments list is indeed
heavier than needed. So when large arrays are used, a method that works on
arrays will be better. But for small arrays of unknown size, spreading them
looks like a nice syntactical help.

@Scott: those functions are indeed interesting too, but their
implementation is a lot more complex AFAICS. If you need to code that
natively, you'll be busy for a while.



2015-04-29 18:56 GMT+02:00 Allen Wirfs-Brock :

>
> On Apr 29, 2015, at 9:04 AM, C. Scott Ananian wrote:
>
> > ...
> > I suppose it would be nice if JavaScript engines fell back to passing
> arguments on the heap to avoid this problem, but I don't think that's part
> of the ES6 spec.  Am I mistaken?
>
> that's an implementation detail. The ES spec. doesn't care whether or not
> you employee multiple argument passing strategies in your implementation.
> Personally, I wouldn't bother unless for some reason the implementation had
> a very small (<10?) stack based argument limit.
>
> Similar, anyone who who wants to spread a large array into an argument
> list is probably misguided.
>
> Allen
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-binding destructuring assignment

2015-04-29 Thread Rick Waldron
On Wed, Apr 29, 2015 at 12:54 PM Tab Atkins Jr. 
wrote:

> On Wed, Apr 29, 2015 at 4:39 AM, Elie Rotenberg  wrote:
> > Using array destructuring assignment and constraining linting rules, I
> often
> > find myself having to chose names for bindings I don't intent on using. I
> > usually end up using a conventional ignore name, such as _ignore, which I
> > "void" to shut up the linter without adding exceptions. Besides the
> linting
> > problem (which can be solved by refining the linting rules), it's still a
> > conceptually useless binding.
> >
> > Here's a contrived example:
> >
> > const lastOfThree = ([first, second, third])  => third;
> >
> > Which I usually end up rewriting:
> >
> > const lastOfThree = ([_ignore1, _ignore2, third]) => {
> >   void _ignore1;
> >   void _ignore2;
> >   return third;
> > }
>
> Honestly, this should probably be answered by fixing the linter, so it
> doesn't give linting errors when a variable named "_" is unused.  (In
> fact, it should probably do the opposite, and give a lint error when _
> *is* used. This'll make users of underscore or lo-dash unhappy,
> though. ^_^)
>
>
Why "_"? A linter can just allow the end developer to define the binding
name.

https://github.com/jshint/jshint/issues/2352

Rick



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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
On Wed, Apr 29, 2015 at 10:26 AM, C. Scott Ananian 
wrote:

> On Wed, Apr 29, 2015 at 1:00 PM, Mark S. Miller 
> wrote:
>
>> The invariant I am interested in:
>>
>> In a realm where we (the trusted defender who runs first) make Promise
>> defensive as follows
>>
>> * Freeze everything primordial, as SES does
>>
>> * Make a DefensivePromise subclass of Promise that differs minimally,
>> hopefully only by ensuring that its instances are frozen.
>>
>> * "Promise = DefensivePromise;" do "Promise" below refers to
>> DefensivePromise
>>
>> * Freezing whitelisted global properties, as SES currently does for ES5
>> globals, but for ES6 including "Promise"
>>
>>
>> then it must be the case that
>>
>> Promise.resolve(anything).then(anycallback)
>>
>> for an anything provided by a potential attacker, when executed in the
>> middle of a turn does not call callback during that turn. If it calls
>> anycallback at all, it calls it back *as* a later turn, i.e., in a later
>> turn starting from an empty stack.
>>
>
> How about:
> ```
> var goodPromises = new WeakSet();
> class DefensivePromise {
>   constructor(x) {
> super(x);
> Object.freeze(x);
> // check this.constructor here if you are paranoid.
> goodPromises.add(this);
>   }
>   resolve(x) {
> if (goodPromises.has(x)) {
>   return super.resolve(x);
> }
> return new DefensivePromise(function(r){r(x);});
>   }
> }
> ```
> Doesn't seem like this needs special support in the Promise spec.
>
> Note that the `goodPromises` set won't be fooled by passing in
> `DefensivePromise` as `new.target` to `Promise` without actually running
> the `DefensivePromise` constructor.
>   --scott
>

Isn't this still vulnerable to the Promise.resolve attack? IIUC, this
attack enables the attacker to cause this.constructor to lie, so how would
checking it help?



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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 1:00 PM, Mark S. Miller  wrote:

> The invariant I am interested in:
>
> In a realm where we (the trusted defender who runs first) make Promise
> defensive as follows
>
> * Freeze everything primordial, as SES does
>
> * Make a DefensivePromise subclass of Promise that differs minimally,
> hopefully only by ensuring that its instances are frozen.
>
> * "Promise = DefensivePromise;" do "Promise" below refers to
> DefensivePromise
>
> * Freezing whitelisted global properties, as SES currently does for ES5
> globals, but for ES6 including "Promise"
>
>
> then it must be the case that
>
> Promise.resolve(anything).then(anycallback)
>
> for an anything provided by a potential attacker, when executed in the
> middle of a turn does not call callback during that turn. If it calls
> anycallback at all, it calls it back *as* a later turn, i.e., in a later
> turn starting from an empty stack.
>

How about:
```
var goodPromises = new WeakSet();
class DefensivePromise {
  constructor(x) {
super(x);
Object.freeze(x);
// check this.constructor here if you are paranoid.
goodPromises.add(this);
  }
  resolve(x) {
if (goodPromises.has(x)) {
  return super.resolve(x);
}
return new DefensivePromise(function(r){r(x);});
  }
}
```
Doesn't seem like this needs special support in the Promise spec.

Note that the `goodPromises` set won't be fooled by passing in
`DefensivePromise` as `new.target` to `Promise` without actually running
the `DefensivePromise` constructor.
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 12:49 PM, Allen Wirfs-Brock 
wrote:

> On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote:
>
On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich  wrote:
>
> Kevin Smith wrote:
>>
>>> So what would the ideal Promise.resolve semantics do?  I'm not sure,
>>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]?
>>>
>>
>> This removes the wart in my view, has no less integrity. C. Scott?
>
>
> Making this concrete, here would be the new text for 25.4.4.5
> Promise.resolve(x):
>
>> The resolve function returns either a new promise resolved with the
>> passed argument, or the argument itself if the argument is a promise
>> produced by this constructor.
>> 1. Let C be the this value.
>> 2. If IsPromise(x) is true,
>> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
>
> b. If SameValue(constructor, C) is true, return x.
>> 3. If Type(C) is not Object, throw a TypeError exception.
>> 4. Let S be Get(C, @@species).
>> 5. ReturnIfAbrupt(S).
>> 6. If S is neither undefined nor null, let C be S.
>> 7. Let promiseCapability be NewPromiseCapability(C)
>
> [...remainer elided...]
>
>
> Step 2a is the only change.  (It was previously "Let constructor be the
> value of x's [[PromiseConstructor]] internal slot.")
>
>
> But SpeciesConstructor (or any access to x's @@species) goes through
> `x.constructor` and my recollection is that the motivation for adding
> [[PromiseConstructor]] was that 'constructor'  was not sufficiently tamper
> proof.  From that perspective, it seems that SpeciesConstructor is actually
> worse than just accessing `x.constructor`.
>
> Also, in a private message Mark Miller mentioned that the primarily
>  security invariant he's concerned about really relates to the behavior of
> the `then` method of the object returned by `Promise.resolve(x)`.  Neither
> testing `construct` or SpeciesConstructor really tells you anything about
> `then`.   It seems that the root problem here is trying to apply nominal
> type based reasoning to JS.
>

I agree that is the root problem.  That is why [[PromiseConstructor]] is
misguided, as (in their own way) is testing x.[[Prototype]] and testing
x.then.  We could imagine rewriting step 2 to test all three of these. And
then maybe we should think about proxies as well!  But rather than add some
complicated test to try to do something which doesn't actually accomplish
its purpose, better to use the simple/expected/consistent thing, which
seems (at this point) to be SpeciesConstructor.   And that seems to make
setting Promise.@@species "work right" as well, for what that's worth.
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Mark S. Miller
I have not responded on list yet because I haven't yet been able to find
the time to absorb this thread. But since Allen mentioned it, what I wrote
was:


The invariant I am interested in:


In a realm where we (the trusted defender who runs first) make Promise
defensive as follows

* Freeze everything primordial, as SES does

* Make a DefensivePromise subclass of Promise that differs minimally,
hopefully only by ensuring that its instances are frozen.

* "Promise = DefensivePromise;" do "Promise" below refers to
DefensivePromise

* Freezing whitelisted global properties, as SES currently does for ES5
globals, but for ES6 including "Promise"


then it must be the case that

Promise.resolve(anything).then(anycallback)

for an anything provided by a potential attacker, when executed in the
middle of a turn does not call callback during that turn. If it calls
anycallback at all, it calls it back *as* a later turn, i.e., in a later
turn starting from an empty stack.








On Wed, Apr 29, 2015 at 9:49 AM, Allen Wirfs-Brock 
wrote:

>
> On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote:
>
> On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich  wrote:
>
>> Kevin Smith wrote:
>>
>>> So what would the ideal Promise.resolve semantics do?  I'm not sure,
>>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]?
>>>
>>
>> This removes the wart in my view, has no less integrity. C. Scott?
>
>
> Making this concrete, here would be the new text for 25.4.4.5
> Promise.resolve(x):
>
>> The resolve function returns either a new promise resolved with the
>> passed argument, or the argument itself if the argument is a promise
>> produced by this constructor.
>> 1. Let C be the this value.
>> 2. If IsPromise(x) is true,
>> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
>
> b. If SameValue(constructor, C) is true, return x.
>> 3. If Type(C) is not Object, throw a TypeError exception.
>> 4. Let S be Get(C, @@species).
>> 5. ReturnIfAbrupt(S).
>> 6. If S is neither undefined nor null, let C be S.
>> 7. Let promiseCapability be NewPromiseCapability(C)
>
> [...remainer elided...]
>
>
> Step 2a is the only change.  (It was previously "Let constructor be the
> value of x's [[PromiseConstructor]] internal slot.")
>
>
> But SpeciesConstructor (or any access to x's @@species) goes through
> `x.constructor` and my recollection is that the motivation for adding
> [[PromiseConstructor]] was that 'constructor'  was not sufficiently tamper
> proof.  From that perspective, it seems that SpeciesConstructor is actually
> worse than just accessing `x.constructor`.
>
> Also, in a private message Mark Miller mentioned that the primarily
>  security invariant he's concerned about really relates to the behavior of
> the `then` method of the object returned by `Promise.resolve(x)`.  Neither
> testing `construct` or SpeciesConstructor really tells you anything about
> `then`.   It seems that the root problem here is trying to apply nominal
> type based reasoning to JS.
>
> Allen
>
>


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


Re: Additional Math functions

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 9:04 AM, C. Scott Ananian wrote:

> ...
> I suppose it would be nice if JavaScript engines fell back to passing 
> arguments on the heap to avoid this problem, but I don't think that's part of 
> the ES6 spec.  Am I mistaken?

that's an implementation detail. The ES spec. doesn't care whether or not you 
employee multiple argument passing strategies in your implementation.  
Personally, I wouldn't bother unless for some reason the implementation had a 
very small (<10?) stack based argument limit.

Similar, anyone who who wants to spread a large array into an argument list is 
probably misguided. 

Allen

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


Re: Non-binding destructuring assignment

2015-04-29 Thread Tab Atkins Jr.
On Wed, Apr 29, 2015 at 4:39 AM, Elie Rotenberg  wrote:
> Using array destructuring assignment and constraining linting rules, I often
> find myself having to chose names for bindings I don't intent on using. I
> usually end up using a conventional ignore name, such as _ignore, which I
> "void" to shut up the linter without adding exceptions. Besides the linting
> problem (which can be solved by refining the linting rules), it's still a
> conceptually useless binding.
>
> Here's a contrived example:
>
> const lastOfThree = ([first, second, third])  => third;
>
> Which I usually end up rewriting:
>
> const lastOfThree = ([_ignore1, _ignore2, third]) => {
>   void _ignore1;
>   void _ignore2;
>   return third;
> }

Honestly, this should probably be answered by fixing the linter, so it
doesn't give linting errors when a variable named "_" is unused.  (In
fact, it should probably do the opposite, and give a lint error when _
*is* used. This'll make users of underscore or lo-dash unhappy,
though. ^_^)

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


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread Allen Wirfs-Brock

On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote:

> On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich  wrote:
> Kevin Smith wrote:
> So what would the ideal Promise.resolve semantics do?  I'm not sure, maybe 
> use SpeciesConstructor instead of [[PromiseConstructor]]?
> 
> This removes the wart in my view, has no less integrity. C. Scott?
> 
> Making this concrete, here would be the new text for 25.4.4.5 
> Promise.resolve(x):
> The resolve function returns either a new promise resolved with the passed 
> argument, or the argument itself if the argument is a promise produced by 
> this constructor.
> 1. Let C be the this value.
> 2. If IsPromise(x) is true,
> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
> b. If SameValue(constructor, C) is true, return x.
> 3. If Type(C) is not Object, throw a TypeError exception.
> 4. Let S be Get(C, @@species).
> 5. ReturnIfAbrupt(S).
> 6. If S is neither undefined nor null, let C be S.
> 7. Let promiseCapability be NewPromiseCapability(C) 
> [...remainer elided...]
>  
> Step 2a is the only change.  (It was previously "Let constructor be the value 
> of x's [[PromiseConstructor]] internal slot.")

But SpeciesConstructor (or any access to x's @@species) goes through 
`x.constructor` and my recollection is that the motivation for adding 
[[PromiseConstructor]] was that 'constructor'  was not sufficiently tamper 
proof.  From that perspective, it seems that SpeciesConstructor is actually 
worse than just accessing `x.constructor`.

Also, in a private message Mark Miller mentioned that the primarily  security 
invariant he's concerned about really relates to the behavior of the `then` 
method of the object returned by `Promise.resolve(x)`.  Neither testing 
`construct` or SpeciesConstructor really tells you anything about `then`.   It 
seems that the root problem here is trying to apply nominal type based 
reasoning to JS.

Allen

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


Re: Non-binding destructuring assignment

2015-04-29 Thread Brendan Eich

Andreas Rossberg wrote:
I agree that we should have wildcard patterns. I also think that array 
elisions are a non-solution, because you need a magnifier to read or 
count them,


Agree.


and they square oddly with optional commas in the end.


Old rule: allowing one (and only one) comma at end for maintainabilitiy 
does not make an elision. For that you need a comma at the front or two 
commas adjacent in the middle. Ok, odd but old too (ES3), and your 
"commas" plural oversold it :-P.


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


Re: is an iterator allowed to reuse the same "state" object?

2015-04-29 Thread Brendan Eich

Andreas Rossberg wrote:
On 29 April 2015 at 02:21, John Lenz > wrote:


I missed it, thanks.I know things will improve in time but I'm
just coming from a discussion with folks complaining about the
performance of generators and GC overhead in real code with Chrome
and Firefox relative to simple hand written loops.


Note that there is a huge difference between optimising iterators (in 
particular, for-of), and optimising generators. I expect that VMs will 
start getting better on the former relatively soon, for iterators that 
are not generators. Making generators fast is a much more complicated 
problem.


But in either case, escape analysis and object allocation elimination 
can avoid the flood of eden objects John cited, right?


I'm inferring your comment about generator optimization hardship has to 
do with a function that yields -- whose CFG has multiple entry points 
and whose activation record must live in the heap.


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


Re: Additional Math functions

2015-04-29 Thread Filip Pizlo


On Apr 29, 2015, at 9:04 AM, C. Scott Ananian mailto:ecmascr...@cscott.net>> wrote:

> Aren't there limits to the number of arguments you can pass to a ES function 
> before getting a stack overflow?

Yup. For example WebKit limits to around 1. This protects our other stack 
overflow detection logic from overflow. 

> 
> I've gotten in trouble trying to abuse the `arguments` array like this 
> before, for example `Math.max.apply(Math, someVeryLargeArray)`.
> 
> Empirically, with iojs 1.8.1:
> ```
> > Math.max.apply(Math, new Array(10))
> NaN
> > Math.max.apply(Math, new Array(100))
> RangeError: Maximum call stack size exceeded
> ```
> I suppose it would be nice if JavaScript engines fell back to passing 
> arguments on the heap to avoid this problem, but I don't think that's part of 
> the ES6 spec.  Am I mistaken?

That would be a great idea!  Filed on our end: 
https://bugs.webkit.org/show_bug.cgi?id=144391 


-Filip

> 
> If we're going to add math functions to the standard library, my vote would 
> be for 
> http://www.evanmiller.org/statistical-shortcomings-in-standard-math-libraries.html
>  
> 
>   --scott
> ​
> ___
> es-discuss mailing list
> es-discuss@mozilla.org 
> https://mail.mozilla.org/listinfo/es-discuss 
> 
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Additional Math functions

2015-04-29 Thread C. Scott Ananian
Aren't there limits to the number of arguments you can pass to a ES
function before getting a stack overflow?

I've gotten in trouble trying to abuse the `arguments` array like this
before, for example `Math.max.apply(Math, someVeryLargeArray)`.

Empirically, with iojs 1.8.1:
```
> Math.max.apply(Math, new Array(10))
NaN
> Math.max.apply(Math, new Array(100))
RangeError: Maximum call stack size exceeded
```
I suppose it would be nice if JavaScript engines fell back to passing
arguments on the heap to avoid this problem, but I don't think that's part
of the ES6 spec.  Am I mistaken?

If we're going to add math functions to the standard library, my vote would
be for
http://www.evanmiller.org/statistical-shortcomings-in-standard-math-libraries.html
  --scott
​
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subclassing ES6 objects with ES5 syntax.

2015-04-29 Thread C. Scott Ananian
On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich  wrote:

> Kevin Smith wrote:
>
>> So what would the ideal Promise.resolve semantics do?  I'm not sure,
>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]?
>>
>
> This removes the wart in my view, has no less integrity. C. Scott?


Making this concrete, here would be the new text for 25.4.4.5
Promise.resolve(x):

> The resolve function returns either a new promise resolved with the passed
> argument, or the argument itself if the argument is a promise produced by
> this constructor.
> 1. Let C be the this value.
> 2. If IsPromise(x) is true,
> a. Let constructor be the value of SpeciesConstructor(x, %Promise%)

b. If SameValue(constructor, C) is true, return x.
> 3. If Type(C) is not Object, throw a TypeError exception.
> 4. Let S be Get(C, @@species).
> 5. ReturnIfAbrupt(S).
> 6. If S is neither undefined nor null, let C be S.
> 7. Let promiseCapability be NewPromiseCapability(C)

[...remainer elided...]


Step 2a is the only change.  (It was previously "Let constructor be the
value of x's [[PromiseConstructor]] internal slot.")

Thinking this through, the purpose of the `@@species` property, from the
spec: "Promise prototype methods normally use their this object’s
constructor to create a derived object. However, a subclass constructor may
over-ride that default behaviour by redefining its @@species property."

So with this change, `P.resolve()` is guaranteed to return an object whose
constructor property is `P.@@species`, whether it takes the shortcut in
step 2 or not.  That seems pleasantly less warty.

The alternative (implemented in core-js) is:

> 2. If IsPromise(x) is true,
> a. Let proto be the value of x.[[Prototype]]

b. If SameValue(proto, GetPrototypeFromConstructor(C,
> "%PromisePrototype%")) is true, return x.
>

But that seems to break the expected behavior of @@species.  That is, a
promise subclass `P1` with `P1.@@species == P2` would shortcut objects of
type `P1` through `P1.resolve()` but return objects of type `P2` if the
shortcut wasn't taken.  (Forgive the looseness of the word "type" here.)

That seems somewhat surprising.  But I don't have a concrete use case in
mind for setting `Promise[@@species]`.  Perhaps someone else has one, and
can say what behavior they'd prefer to see?

Lacking such a justification, the first alternative (using
[[SpeciesConstructor]]) seems to be more consistent with the rest of the
spec and less surprising.  So that has my vote.
  --scott
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Additional Math functions

2015-04-29 Thread Sander Deryckere
IMHO, there are still some rather basic Math functions missing in ES.

1. `Math.sum([value1[, value2[, value3[, ...)`

A Math.sum() function would mostly be handy thanks to the spread operator.
So you can sum a complete array. Being able to do

```
var sum = Math.sum(...arr);
```

would be so much cleaner than

```
var sum = arr.reduce((a,b) => a + b);
```

Even though arrow functions make it a lot more concise than before, the
code with Math.sum is still a lot easier to read IMO.

Reference implementation:
```
Math.sum = function() {
  var sum = 0;
  var length = arguments.length;

  for (var i = 0; i < length; i++) {
sum += +arguments[i]; // note the conversion to number, to avoid string
concatenation
  }
  return sum;
};
```

2. `Math.avg(value1[, value2[, value3[, ...]]])`

Calculating the average is just the sum divided by the number of values.
This might be less used, and when Math.sum is implemented, it might even be
clean enough to type something like

```
var avg = Math.sum(...arr) / arr.length;
```

Maybe it's also not used as often as summing an array. But I still expect
it would enhance the vanilla ES experience.

Reference implementation:
```
Math.avg = function() {
  var sum = 0;
  var length = arguments.length;

  for (var i = 0; i < length; i++) {
sum += +arguments[i]; // note the conversion to number, to avoid string
concatenation
  }
  return sum / length;
}
```

3. `Math.clamp(value, min, max)`

This would basically be the same as
```
Math.max(Math.min(value, max), min);
```

Perhaps with extra consistency checks, throwing a rangeError when min>max
for example. The problem with combining Math.min and Math.max to achieve a
clamp function is that it's way too easy to mix them up, and get bugs in
your code.



There are of course other math functions that could be added (like the list
here: http://moutjs.com/docs/latest/math.html ), but I think that these
will be the more useful ones (also used more often than Math.hypot I
assume).

I do understand that a bloated language is in nobody's interest, but when
using reduce to sum an array, I always wondered if there's no other way to
do it. Without hacking on the language, and by typing what you mean. Thanks
to the spread operator, there now is a way to define such a function, but
sadly, there's no default function like that yet.

Thanks for your consideration,
Sander
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Declaration binding instationationing

2015-04-29 Thread Garrett Smith
OK, here is a bug report:

Bug 4336 - 10.5 Declaration binding instantiation
https://bugs.ecmascript.org/show_bug.cgi?id=4336

On 4/29/15, Mathias Bynens  wrote:
> On Wed, Apr 29, 2015 at 7:29 AM, Garrett Smith 
> wrote:
>> There is an English problem here:
>>
>> Let existingProp be the resulting of calling the [[GetProperty]]
>> internal method of go with argument fn.
>
> s/resulting/result/ indeed.
>
>> Can the spec be made easier to read?
>
> FYI, the best way to go about this is to file a spec bug on
> https://bugs.ecmascript.org/ under the "editorial issue" component.
>


-- 
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: is an iterator allowed to reuse the same "state" object?

2015-04-29 Thread Andreas Rossberg
On 29 April 2015 at 02:21, John Lenz  wrote:

> I missed it, thanks.I know things will improve in time but I'm just
> coming from a discussion with folks complaining about the performance of
> generators and GC overhead in real code with Chrome and Firefox relative to
> simple hand written loops.
>

Note that there is a huge difference between optimising iterators (in
particular, for-of), and optimising generators. I expect that VMs will
start getting better on the former relatively soon, for iterators that are
not generators. Making generators fast is a much more complicated problem.

/Andreas


On Tue, Apr 28, 2015 at 4:28 PM, Allen Wirfs-Brock 
> wrote:
>
>>
>> On Apr 28, 2015, at 4:21 PM, John Lenz wrote:
>>
>> You would hope that the engines might be able to create these objects on
>> the stack but I don't think anyone does that yet and the result is a flood
>> of eden objects.
>>
>> I would like to know I'm wrong about this.
>>
>> did you see
>> https://esdiscuss.org/topic/performance-of-iterator-next-as-specified#content-15
>>
>>
>> A really good optimizing jit should be able to inline the 'next' call,
>> recognize that the IterationResult object doesn't escape (it knows this for
>> for-of loops) and not do an allocation at all.
>>
>> Allen
>>
>>
>>
>> On Apr 27, 2015 4:59 PM, "Allen Wirfs-Brock" 
>> wrote:
>>
>>>
>>> On Apr 27, 2015, at 3:29 PM, Tab Atkins Jr. wrote:
>>>
>>> On Mon, Apr 27, 2015 at 3:11 PM, John Lenz 
>>> wrote:
>>>
>>> By which I mean the object that returns the current value and "done"
>>> state?
>>>
>>>
>>> IIRC, it's not supposed to.  The built-in iterators will return fresh
>>> objects each time, so there's no mutation hazard.  Userland iterators
>>> can of course violate this, but at their peril.
>>>
>>>
>>> Well, that's not exactly what the ES2015 spec. says.  The specification
>>> of the Iterator interface (
>>> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-iterator-interface 
>>> )
>>> does not require that the `next` method return a fresh object each time it
>>> it called.  So a userland iterator would not be violating anything by
>>> reusing a result object.
>>>
>>> However,  the specifications for all ES2015  built-in iterators require
>>> that they return fresh objects.
>>>
>>> None of the built-in consumers of the Iterator interface (for-of,
>>> Array.from, etc.) retain references to IteratorResult objects after testing
>>> for `done` and accessing the `value`, so semantically they don't care
>>> whether the ResultObject is reused. However, such reuse might preclude some
>>> otherwise plausible engine level optimizations.
>>>
>>> Allen
>>>
>>>
>>>
>>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-binding destructuring assignment

2015-04-29 Thread Andreas Rossberg
I agree that we should have wildcard patterns. I also think that array
elisions are a non-solution, because you need a magnifier to read or count
them, and they square oddly with optional commas in the end.

/Andreas

On 29 April 2015 at 13:47, Elie Rotenberg  wrote:

> Wow, thanks. I feel dumb for asking :D
>
> On Wed, Apr 29, 2015 at 1:43 PM, Sebastian McKenzie 
> wrote:
>
>> The binding identifiers are optional. You can do what you want already
>> with:
>>
>> const lastOfThree = ([,, third]) => {
>>   return third;
>> }
>>
>>
>>
>>
>> On Wed, Apr 29, 2015 at 12:40 PM, Elie Rotenberg 
>> wrote:
>>
>>> Using array destructuring assignment and constraining linting rules, I
>>> often find myself having to chose names for bindings I don't intent on
>>> using. I usually end up using a conventional ignore name, such as _ignore,
>>> which I "void" to shut up the linter without adding exceptions. Besides the
>>> linting problem (which can be solved by refining the linting rules), it's
>>> still a conceptually useless binding.
>>>
>>> Here's a contrived example:
>>>
>>> const lastOfThree = ([first, second, third])  => third;
>>>
>>> Which I usually end up rewriting:
>>>
>>> const lastOfThree = ([_ignore1, _ignore2, third]) => {
>>>   void _ignore1;
>>>   void _ignore2;
>>>   return third;
>>> }
>>>
>>> This problem doesn't exist when using objects, since only the fields
>>> specified on the LHS are bound.
>>>
>>> I realize the bigger topic behind non-binding match is refutable pattern
>>> matching, as per
>>> http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching, but
>>> being able to dismiss a matched (or unmatched) value from a destructuring
>>> assignment seems a very often desirable feature when programming in a
>>> functional style (eg. working with lists represented as 2-element arrays).
>>> Most functional-style languages have a non-binding matching feature.
>>>
>>> This topic has been discussed in the following topics:
>>> - https://esdiscuss.org/topic/conditional-catch
>>> - https://esdiscuss.org/notes/2014-07-30
>>> - https://esdiscuss.org/topic/conditional-catch-clause
>>>
>>> Does anyone else feel the need for a specific means of dismissing a
>>> binding from a destructuring assignment? Is pattern matching still on
>>> discussion?
>>>
>>> Regards,
>>>
>>
>>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-binding destructuring assignment

2015-04-29 Thread Elie Rotenberg
Wow, thanks. I feel dumb for asking :D

On Wed, Apr 29, 2015 at 1:43 PM, Sebastian McKenzie 
wrote:

> The binding identifiers are optional. You can do what you want already
> with:
>
> const lastOfThree = ([,, third]) => {
>   return third;
> }
>
>
>
>
> On Wed, Apr 29, 2015 at 12:40 PM, Elie Rotenberg 
> wrote:
>
>> Using array destructuring assignment and constraining linting rules, I
>> often find myself having to chose names for bindings I don't intent on
>> using. I usually end up using a conventional ignore name, such as _ignore,
>> which I "void" to shut up the linter without adding exceptions. Besides the
>> linting problem (which can be solved by refining the linting rules), it's
>> still a conceptually useless binding.
>>
>> Here's a contrived example:
>>
>> const lastOfThree = ([first, second, third])  => third;
>>
>> Which I usually end up rewriting:
>>
>> const lastOfThree = ([_ignore1, _ignore2, third]) => {
>>   void _ignore1;
>>   void _ignore2;
>>   return third;
>> }
>>
>> This problem doesn't exist when using objects, since only the fields
>> specified on the LHS are bound.
>>
>> I realize the bigger topic behind non-binding match is refutable pattern
>> matching, as per
>> http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching, but
>> being able to dismiss a matched (or unmatched) value from a destructuring
>> assignment seems a very often desirable feature when programming in a
>> functional style (eg. working with lists represented as 2-element arrays).
>> Most functional-style languages have a non-binding matching feature.
>>
>> This topic has been discussed in the following topics:
>> - https://esdiscuss.org/topic/conditional-catch
>> - https://esdiscuss.org/notes/2014-07-30
>> - https://esdiscuss.org/topic/conditional-catch-clause
>>
>> Does anyone else feel the need for a specific means of dismissing a
>> binding from a destructuring assignment? Is pattern matching still on
>> discussion?
>>
>> Regards,
>>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-binding destructuring assignment

2015-04-29 Thread Sebastian McKenzie
The binding identifiers are optional. You can do what you want already with:




const lastOfThree = ([,, third]) => {

  return third;

}

On Wed, Apr 29, 2015 at 12:40 PM, Elie Rotenberg 
wrote:

> Using array destructuring assignment and constraining linting rules, I
> often find myself having to chose names for bindings I don't intent on
> using. I usually end up using a conventional ignore name, such as _ignore,
> which I "void" to shut up the linter without adding exceptions. Besides the
> linting problem (which can be solved by refining the linting rules), it's
> still a conceptually useless binding.
> Here's a contrived example:
> const lastOfThree = ([first, second, third])  => third;
> Which I usually end up rewriting:
> const lastOfThree = ([_ignore1, _ignore2, third]) => {
>   void _ignore1;
>   void _ignore2;
>   return third;
> }
> This problem doesn't exist when using objects, since only the fields
> specified on the LHS are bound.
> I realize the bigger topic behind non-binding match is refutable pattern
> matching, as per
> http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching, but being
> able to dismiss a matched (or unmatched) value from a destructuring
> assignment seems a very often desirable feature when programming in a
> functional style (eg. working with lists represented as 2-element arrays).
> Most functional-style languages have a non-binding matching feature.
> This topic has been discussed in the following topics:
> - https://esdiscuss.org/topic/conditional-catch
> - https://esdiscuss.org/notes/2014-07-30
> - https://esdiscuss.org/topic/conditional-catch-clause
> Does anyone else feel the need for a specific means of dismissing a binding
> from a destructuring assignment? Is pattern matching still on discussion?
> Regards,___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Non-binding destructuring assignment

2015-04-29 Thread Elie Rotenberg
Using array destructuring assignment and constraining linting rules, I
often find myself having to chose names for bindings I don't intent on
using. I usually end up using a conventional ignore name, such as _ignore,
which I "void" to shut up the linter without adding exceptions. Besides the
linting problem (which can be solved by refining the linting rules), it's
still a conceptually useless binding.

Here's a contrived example:

const lastOfThree = ([first, second, third])  => third;

Which I usually end up rewriting:

const lastOfThree = ([_ignore1, _ignore2, third]) => {
  void _ignore1;
  void _ignore2;
  return third;
}

This problem doesn't exist when using objects, since only the fields
specified on the LHS are bound.

I realize the bigger topic behind non-binding match is refutable pattern
matching, as per
http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching, but being
able to dismiss a matched (or unmatched) value from a destructuring
assignment seems a very often desirable feature when programming in a
functional style (eg. working with lists represented as 2-element arrays).
Most functional-style languages have a non-binding matching feature.

This topic has been discussed in the following topics:
- https://esdiscuss.org/topic/conditional-catch
- https://esdiscuss.org/notes/2014-07-30
- https://esdiscuss.org/topic/conditional-catch-clause

Does anyone else feel the need for a specific means of dismissing a binding
from a destructuring assignment? Is pattern matching still on discussion?

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


Re: Declaration binding instationationing

2015-04-29 Thread Mathias Bynens
On Wed, Apr 29, 2015 at 7:29 AM, Garrett Smith  wrote:
> There is an English problem here:
>
> Let existingProp be the resulting of calling the [[GetProperty]]
> internal method of go with argument fn.

s/resulting/result/ indeed.

> Can the spec be made easier to read?

FYI, the best way to go about this is to file a spec bug on
https://bugs.ecmascript.org/ under the “editorial issue” component.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss