Re: extends null

2015-02-15 Thread Marius Gundersen
>>> The purpose would be defining a class whose instances don't have
Object.prototype on their prototype chain.  If "extends null" doesn't work,
then I think you'd have to do something like this to achieve the same?
>>>
>>> function NullBase() {}
>>> NullBase.prototype = Object.create(null);
>>>
>>> class C extends NullBase {}
>>>

Can't this be solved by returning a null object from the constructor?

```js
class Null{
  constructor() {
return Object.create(null);
}
}

class MyClass extends Null{

}
let foo = new MyClass();
foo.toString() //ReferenceError
```

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


Re: Suggestion: for-of-and loops

2015-02-15 Thread Brendan Eich

Kevin Smith wrote:


Have you tried writing a combinator which does exactly that? Take a 
look at zip in python.




Right -- we don't add new syntax lightly, we'd need to see zip used a 
lot, and at some irreducible-without-special-form overhead.


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


Re: extends null

2015-02-15 Thread Jordan Harband
Rather than making "extends null" alone a runtime error at class evaluation
time, is there a reason not to instead, make only a reference to "super" in
the constructor of a class that extends null be a runtime error at class
evaluation time?

On Sun, Feb 15, 2015 at 11:12 AM, Mark S. Miller  wrote:

>
>
> On Sun, Feb 15, 2015 at 11:01 AM, Kevin Smith 
> wrote:
>
>>
>>> Interesting. I have never seen this pattern and don’t see what it could
>>> be good for. Thus, a dynamic error at class definition time sounds good to
>>> me.
>>>
>>
>> The purpose would be defining a class whose instances don't have
>> Object.prototype on their prototype chain.  If "extends null" doesn't work,
>> then I think you'd have to do something like this to achieve the same?
>>
>> function NullBase() {}
>> NullBase.prototype = Object.create(null);
>>
>> class C extends NullBase {}
>>
>>
> That still wouldn't work at runtime because of the super semantics of C as
> a derived class. Instead
>
>
> class C {}
>
> C.prototype.__proto__ = null;
>
> Yes, it is ugly, but it is an odd case, so still obeys Kay's dictum:
>
>
> "Simple things should be simple. Complex things should be possible"
> --Alan Kay
>
>
>
>
>
> --
> Cheers,
> --MarkM
>
> ___
> 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: extends null

2015-02-15 Thread Mark S. Miller
On Sun, Feb 15, 2015 at 11:01 AM, Kevin Smith  wrote:

>
>> Interesting. I have never seen this pattern and don’t see what it could
>> be good for. Thus, a dynamic error at class definition time sounds good to
>> me.
>>
>
> The purpose would be defining a class whose instances don't have
> Object.prototype on their prototype chain.  If "extends null" doesn't work,
> then I think you'd have to do something like this to achieve the same?
>
> function NullBase() {}
> NullBase.prototype = Object.create(null);
>
> class C extends NullBase {}
>
>
That still wouldn't work at runtime because of the super semantics of C as
a derived class. Instead


class C {}

C.prototype.__proto__ = null;

Yes, it is ugly, but it is an odd case, so still obeys Kay's dictum:


"Simple things should be simple. Complex things should be possible"
--Alan Kay





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


Re: extends null

2015-02-15 Thread Kevin Smith
>
>
> Interesting. I have never seen this pattern and don’t see what it could be
> good for. Thus, a dynamic error at class definition time sounds good to me.
>

The purpose would be defining a class whose instances don't have
Object.prototype on their prototype chain.  If "extends null" doesn't work,
then I think you'd have to do something like this to achieve the same?

function NullBase() {}
NullBase.prototype = Object.create(null);

class C extends NullBase {}
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: extends null

2015-02-15 Thread Axel Rauschmayer
> Making it a dynamic error at class definition time to extend null would work 
> but the motivation for not doing that was that someone might want to create a 
> class that has a {__proto__: null} prototype. Personally, I would be fine 
> with saying that this case is so rare that it would be better to have that 
> dynamic error at class definition time.

Interesting. I have never seen this pattern and don’t see what it could be good 
for. Thus, a dynamic error at class definition time sounds good to me.

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



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


Re: extends null

2015-02-15 Thread Erik Arvidsson
Making it a dynamic error at class definition time to extend null would
work but the motivation for not doing that was that someone might want to
create a class that has a {__proto__: null} prototype. Personally, I would
be fine with saying that this case is so rare that it would be better to
have that dynamic error at class definition time.

On Sat Feb 14 2015 at 4:52:40 PM Mark S. Miller  wrote:

> On Sat, Feb 14, 2015 at 1:45 PM, Axel Rauschmayer 
> wrote:
>
>>
>> On 14 Feb 2015, at 22:26, Mark S. Miller  wrote:
>>
>> On Sat, Feb 14, 2015 at 1:21 PM, Axel Rauschmayer 
>> wrote:
>>
>>> But it’s not an error! Either of the following two classes fail later,
>>> when you instantiate them, but not right away.
>>>
>>> ```js
>>> const X = null;
>>> class C extends X {}
>>>
>>> class D extends null {}
>>> ```
>>>
>>
>> I didn't mean to imply an early error. The "extends X" can only produce a
>> dynamic error, so I'm arguing that "extends null" should do the same.
>>
>>
>> When I say “early”, I don’t mean “static”, I mean: dynamically, when the
>> class definition is evaluated, not later when the class is instantiated via
>> `new`.
>>
>> I’m not seeing a dynamic error in the spec when the `extends` clause is
>> null (step 6e):
>> https://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation
>>
>
>
> That's a good suggestion. AFAICT, it would be an improvement. I don't see
> any downside.
>
> Allen?
>
>
>
>>
>>
>>> Or dynamically switching from "derived" to "base" (but you seem to be
>>> saying that doing this dynamically is not a good idea).
>>>
>>
>> Dynamically switching from derived to base does not work, because our
>> super semantics depends statically on the difference.
>>
>>
>> Ah, checked statically, I wasn’t aware! Hadn’t found the check
>> beforehand. Searched some more and it is indeed there, in 14.5.1.
>>
>> --
>> Dr. Axel Rauschmayer
>> a...@rauschma.de
>> rauschma.de
>>
>>
>>
>>
>
>
> --
> Cheers,
> --MarkM
>  ___
> 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: Subject: Performance of iterator .next() as specified

2015-02-15 Thread joe
Sorry about that, I think I'm unconsciously substituting "return value of
.next" for ".next.value."  I am talking about reusing the return object,
yes; for some reason in my head, "return object of .next" refers to
.next(), while "return value of .next" refers to .next().value.
Communication error on my part.



On Sun, Feb 15, 2015 at 8:19 AM, Benjamin (Inglor) Gruenbaum <
ing...@gmail.com> wrote:

> Joe, I don't think we're having the same discussion.
>
> Again, this is about the issue Katelyn raised about the return value of
> `.next`.
>
> Katelyn suggested that the return value of a `.next` call in the iteration
> protocol - an object of the form `{value: value, done: boolean}` should be
> allowed to be reused between calls - so an iterator can return _the same_
> object without allocating a new one.
>
> I argue (and from what I understand Kevin agrees with me) that allowing
> this is error prone and might cause surprises for developers since they
> have an object returned that has mutated implicitly without the consumer
> being aware. We can have the same performance gain by a clever engine that
> figures this sort of thing out itself.
>
>
> On Sun, Feb 15, 2015 at 4:13 PM, joe  wrote:
>
>> Again, where does this mutation occur?  The spec shouldn't allow any such
>> thing to begin with; it should mandate exactly what my compiler does: as
>> soon as .next returns, copy .value into the loop variable.  The developer
>> shouldn't have any access to the return value from within the loop at all;
>> if he does, that should (ideally) be considered a violation of the standard.
>>
>> On Sun, Feb 15, 2015 at 8:09 AM, Kevin Smith 
>> wrote:
>>
>>> When I can get more sound abstractions for no additional cost
 (eventually) I'd rather not introduce implicit mutable state into the
 application. Developers won't be aware of it being mutating and the whole
 notion of a mutating-at-a-later-point return value is very error-prone in
 my opinion.

>>>
>>> Right. Mutating the returned object isn't really tenable from a
>>> usability point of view.
>>>
>>>
>>> ___
>>> 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: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Benjamin (Inglor) Gruenbaum
Joe, I don't think we're having the same discussion.

Again, this is about the issue Katelyn raised about the return value of
`.next`.

Katelyn suggested that the return value of a `.next` call in the iteration
protocol - an object of the form `{value: value, done: boolean}` should be
allowed to be reused between calls - so an iterator can return _the same_
object without allocating a new one.

I argue (and from what I understand Kevin agrees with me) that allowing
this is error prone and might cause surprises for developers since they
have an object returned that has mutated implicitly without the consumer
being aware. We can have the same performance gain by a clever engine that
figures this sort of thing out itself.


On Sun, Feb 15, 2015 at 4:13 PM, joe  wrote:

> Again, where does this mutation occur?  The spec shouldn't allow any such
> thing to begin with; it should mandate exactly what my compiler does: as
> soon as .next returns, copy .value into the loop variable.  The developer
> shouldn't have any access to the return value from within the loop at all;
> if he does, that should (ideally) be considered a violation of the standard.
>
> On Sun, Feb 15, 2015 at 8:09 AM, Kevin Smith  wrote:
>
>> When I can get more sound abstractions for no additional cost
>>> (eventually) I'd rather not introduce implicit mutable state into the
>>> application. Developers won't be aware of it being mutating and the whole
>>> notion of a mutating-at-a-later-point return value is very error-prone in
>>> my opinion.
>>>
>>
>> Right. Mutating the returned object isn't really tenable from a usability
>> point of view.
>>
>>
>> ___
>> 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: Subject: Performance of iterator .next() as specified

2015-02-15 Thread joe
Again, where does this mutation occur?  The spec shouldn't allow any such
thing to begin with; it should mandate exactly what my compiler does: as
soon as .next returns, copy .value into the loop variable.  The developer
shouldn't have any access to the return value from within the loop at all;
if he does, that should (ideally) be considered a violation of the standard.

On Sun, Feb 15, 2015 at 8:09 AM, Kevin Smith  wrote:

> When I can get more sound abstractions for no additional cost (eventually)
>> I'd rather not introduce implicit mutable state into the application.
>> Developers won't be aware of it being mutating and the whole notion of a
>> mutating-at-a-later-point return value is very error-prone in my opinion.
>>
>
> Right. Mutating the returned object isn't really tenable from a usability
> point of view.
>
>
> ___
> 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: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Kevin Smith
>
> When I can get more sound abstractions for no additional cost (eventually)
> I'd rather not introduce implicit mutable state into the application.
> Developers won't be aware of it being mutating and the whole notion of a
> mutating-at-a-later-point return value is very error-prone in my opinion.
>

Right. Mutating the returned object isn't really tenable from a usability
point of view.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread joe
On Sun, Feb 15, 2015 at 7:43 AM, Benjamin (Inglor) Gruenbaum <
ing...@gmail.com> wrote:

> This is actually exactly the kind of slow code Katelyn was talking about.
> Also, you probably meant `set[Symbol.iterator]()` and `for... of`.
>

You are correct.  I haven't switched to the 'of' syntax yet (need to do
that).


>
> What Katelyn is talking about is optimizing .next in the example code to
> not return a new object but to return the same one every time with
> different values filled in. In order to optimize that with your transpiler
> you'd need to implement your own `Set` and `Map` because like Katelyn
> correctly noted `Set` and `Map` do not expose a fast way (in current
> implementations) to iterate them at the moment - at least until engines
> optimize them
>

I did implement my own, yes.

>
>

> Katelyn is arguing it would be useful to allow the implementation to
> return the same instance and I'm arguing the reason it's slow is because
> it's benchmarked against a slow implementation that was not optimized yet
> but can easily be - just like Katelyn noted as LuaJIT does.
>

I may have misunderstood; it sounded to me like the two of you were
agreeing that JS VMs won't be doing this anytime soon.


>
>

> When I can get more sound abstractions for no additional cost (eventually)
> I'd rather not introduce implicit mutable state into the application.
> Developers won't be aware of it being mutating and the whole notion of a
> mutating-at-a-later-point return value is very error-prone in my opinion.
>

Exactly how would developers mutate the return object in the first place?
And frankly, I don't see how you can care so little about a major,
show-stopping issue such as this.  JS performance has gotten to the point
where people like me write *CAD software* in it.  Usable iterators are
important for such things.

Frankly, I find this sudden embrace of good coding practices odd in a
language that practically sets the floor for how horrendously mutable a
dynamic runtime language can get.


>
> On Sun, Feb 15, 2015 at 3:35 PM, joe  wrote:
>
>
>>
>> On Sun, Feb 15, 2015 at 7:16 AM, Benjamin (Inglor) Gruenbaum <
>> ing...@gmail.com> wrote:
>>
>>>
>>> This is something that can be solved at the VM level. VMs perform much
>>> much smarter optimizations than this already. There is no reason to
>>> sacrifice code correctness and the principle of least astonishment in order
>>> to get acceptable performance. Benchmarking against "proof of concept"
>>> implementations is counter-productive in my opinion. The engines are
>>> already 'allowed' to use the same object when there is no observable
>>> difference. Even if we allow this 'optimization' it will take the engines
>>> as much time to implement it so there is no gain from this anyway.
>>>
>>> __
>>>
>>
>> Is 60,000 lines of source code a good enough "proof of concept for you"?
>>
>> I don't see what the problem is.  My transpiler generators the following
>> ES5 code:
>>
>> //for (var item in set)
>>
>> var iter = obj.iterator();
>> while (1) {
>>var ret = obj.next();
>>
>>if (ret.done) break;
>>var item = ret.value;
>>...loop body
>> }
>>
>> It works quite well.  You may be right about the VM vendors, however.
>> This requirement basically makes JS useless for anything other than minor
>> scripting tasks.  The VM people may not have any choice but to optimize it.
>>
>> Joe
>>
>>
> On Sun, Feb 15, 2015 at 3:35 PM, joe  wrote:
>
>>
>>
>> On Sun, Feb 15, 2015 at 7:16 AM, Benjamin (Inglor) Gruenbaum <
>> ing...@gmail.com> wrote:
>>
>>>
>>> This is something that can be solved at the VM level. VMs perform much
>>> much smarter optimizations than this already. There is no reason to
>>> sacrifice code correctness and the principle of least astonishment in order
>>> to get acceptable performance. Benchmarking against "proof of concept"
>>> implementations is counter-productive in my opinion. The engines are
>>> already 'allowed' to use the same object when there is no observable
>>> difference. Even if we allow this 'optimization' it will take the engines
>>> as much time to implement it so there is no gain from this anyway.
>>>
>>> __
>>>
>>
>> Is 60,000 lines of source code a good enough "proof of concept for you"?
>>
>> I don't see what the problem is.  My transpiler generators the following
>> ES5 code:
>>
>> //for (var item in set)
>>
>> var iter = obj.iterator();
>> while (1) {
>>var ret = obj.next();
>>
>>if (ret.done) break;
>>var item = ret.value;
>>...loop body
>> }
>>
>> It works quite well.  You may be right about the VM vendors, however.
>> This requirement basically makes JS useless for anything other than minor
>> scripting tasks.  The VM people may not have any choice but to optimize it.
>>
>> Joe
>>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-dis

Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Benjamin (Inglor) Gruenbaum
This is actually exactly the kind of slow code Katelyn was talking about.
Also, you probably meant `set[Symbol.iterator]()` and `for... of`.

What Katelyn is talking about is optimizing .next in the example code to
not return a new object but to return the same one every time with
different values filled in. In order to optimize that with your transpiler
you'd need to implement your own `Set` and `Map` because like Katelyn
correctly noted `Set` and `Map` do not expose a fast way (in current
implementations) to iterate them at the moment - at least until engines
optimize them.

Katelyn is arguing it would be useful to allow the implementation to return
the same instance and I'm arguing the reason it's slow is because it's
benchmarked against a slow implementation that was not optimized yet but
can easily be - just like Katelyn noted as LuaJIT does.

When I can get more sound abstractions for no additional cost (eventually)
I'd rather not introduce implicit mutable state into the application.
Developers won't be aware of it being mutating and the whole notion of a
mutating-at-a-later-point return value is very error-prone in my opinion.

On Sun, Feb 15, 2015 at 3:35 PM, joe  wrote:

>
>
> On Sun, Feb 15, 2015 at 7:16 AM, Benjamin (Inglor) Gruenbaum <
> ing...@gmail.com> wrote:
>
>>
>> This is something that can be solved at the VM level. VMs perform much
>> much smarter optimizations than this already. There is no reason to
>> sacrifice code correctness and the principle of least astonishment in order
>> to get acceptable performance. Benchmarking against "proof of concept"
>> implementations is counter-productive in my opinion. The engines are
>> already 'allowed' to use the same object when there is no observable
>> difference. Even if we allow this 'optimization' it will take the engines
>> as much time to implement it so there is no gain from this anyway.
>>
>> __
>>
>
> Is 60,000 lines of source code a good enough "proof of concept for you"?
>
> I don't see what the problem is.  My transpiler generators the following
> ES5 code:
>
> //for (var item in set)
>
> var iter = obj.iterator();
> while (1) {
>var ret = obj.next();
>
>if (ret.done) break;
>var item = ret.value;
>...loop body
> }
>
> It works quite well.  You may be right about the VM vendors, however.
> This requirement basically makes JS useless for anything other than minor
> scripting tasks.  The VM people may not have any choice but to optimize it.
>
> Joe
>
>
On Sun, Feb 15, 2015 at 3:35 PM, joe  wrote:

>
>
> On Sun, Feb 15, 2015 at 7:16 AM, Benjamin (Inglor) Gruenbaum <
> ing...@gmail.com> wrote:
>
>>
>> This is something that can be solved at the VM level. VMs perform much
>> much smarter optimizations than this already. There is no reason to
>> sacrifice code correctness and the principle of least astonishment in order
>> to get acceptable performance. Benchmarking against "proof of concept"
>> implementations is counter-productive in my opinion. The engines are
>> already 'allowed' to use the same object when there is no observable
>> difference. Even if we allow this 'optimization' it will take the engines
>> as much time to implement it so there is no gain from this anyway.
>>
>> __
>>
>
> Is 60,000 lines of source code a good enough "proof of concept for you"?
>
> I don't see what the problem is.  My transpiler generators the following
> ES5 code:
>
> //for (var item in set)
>
> var iter = obj.iterator();
> while (1) {
>var ret = obj.next();
>
>if (ret.done) break;
>var item = ret.value;
>...loop body
> }
>
> It works quite well.  You may be right about the VM vendors, however.
> This requirement basically makes JS useless for anything other than minor
> scripting tasks.  The VM people may not have any choice but to optimize it.
>
> Joe
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread joe
On Sun, Feb 15, 2015 at 7:16 AM, Benjamin (Inglor) Gruenbaum <
ing...@gmail.com> wrote:

>
> This is something that can be solved at the VM level. VMs perform much
> much smarter optimizations than this already. There is no reason to
> sacrifice code correctness and the principle of least astonishment in order
> to get acceptable performance. Benchmarking against "proof of concept"
> implementations is counter-productive in my opinion. The engines are
> already 'allowed' to use the same object when there is no observable
> difference. Even if we allow this 'optimization' it will take the engines
> as much time to implement it so there is no gain from this anyway.
>
> __
>

Is 60,000 lines of source code a good enough "proof of concept for you"?

I don't see what the problem is.  My transpiler generators the following
ES5 code:

//for (var item in set)

var iter = obj.iterator();
while (1) {
   var ret = obj.next();

   if (ret.done) break;
   var item = ret.value;
   ...loop body
}

It works quite well.  You may be right about the VM vendors, however.  This
requirement basically makes JS useless for anything other than minor
scripting tasks.  The VM people may not have any choice but to optimize it.

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


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Katelyn Gadd
So there's no point in going in circles here, I just want to address
the statement:
Even if we allow this 'optimization' it will take the engines as much
time to implement it so there is no gain from this anyway.

My premise is that this is a rather obvious bottleneck and it applies
to new APIs with no for-loop equivalent. As far as I know, I cannot
use a for-loop to iterate over a Map or Set. So if I want to iterate
over Map or Set, I'm eating the cost of the current iterator API as
specified. The alternative is to use a custom implementation of those
containers (that is what I do right now, and will continue to do.)

Given the constraint that the .next() method is self-hosted in JS, my
proposal is trivial to implement. I think this is a reasonable
constraint, even though at present the API does not appear to be
self-hosted in SpiderMonkey. Many builtins are self-hosted in both
runtimes at present and more become self-hosted on a regular basis.
The current self-hosted JS would look like this:

function Iterator () {
  // ...
}

function next () {
  // ...
  return {
done: isDone,
value: value
  };
}

The proposal would change the self-hosted JS to:

function Iterator () {
  // ...
  this.$cachedResultObject = { done: false, value: null };
}

function next () {
  // ...
  this.$cachedResultObject.done = isDone;
  this.$cachedResultObject.value = value;
  return this.$cachedResultObject;
}

As long as the spec allows this behavior change (it's certainly
observable), that's all you really have to do at a basic level to make
this work. I hope it is obvious that a C++ engine-level implementation
of this optimization is not *significantly* more complex, though I
will not say it is 'easy'.

It is certainly, absolutely, I-will-bet-you-real-money simpler to do
this than to implement sufficiently smart escape analysis to be able
to optimize out the new object. I think if the next() method were
self-hosted and fully inlined into the caller, at that point it would
be possible for the .done and .value sets to be store-to-load
forwarded and the new object optimized out. That's the most realistic
case I can think of; I have yet to see a VM do that but I can imagine
it happening sometime soon, given that LuaJIT does it.

-kg

On 15 February 2015 at 07:16, Benjamin (Inglor) Gruenbaum
 wrote:
> On Sun, Feb 15, 2015 at 3:06 PM, Katelyn Gadd  wrote:
>>
>> In my testing Map and Set are outperformed by a trivial Object or
>> Array based data structure in every case, *despite the fact* that
>> using an Object as a Map requires the use of Object.keys() to be able
>> to sequentially iterate elements. The cost of iterator.next() in v8
>> and spidermonkey is currently extremely profound and profiling shows
>> all the time is being spent in object creation and GC. (To be fair,
>> self-hosting of iterations might improve on this some.)
>
>
> Yes, this is of course true simply because iterating Set/Map was not
> optimized yet in V8/SpiderMoney since usually features are first implemented
> and then optimized. Benchmarking current naive engine implementations to
> make conclusions about the spec is a very risky thing to do. It's entirely
> possible for engines to optimize this. By the same logic I could say that
> `const` has bad performance because how it is currently implemented as much
> much slower than `var` in V8.
>
>> I am sure that given some sufficient amount of compiler engineering,
> the allocations could be entirely optimized out, but this is far from
> a trivial case so odds are it will not happen soon.
>
> Right, I agree with you there it probably won't happen soon. Changing the
> spec won't change that fact. Remember that the engine doesn't actually need
> to allocate a new object in cases where it can reuse the old one safely
> since it's not used anymore - again, this can be solved at the engine level.
>
>> My point is that for my current test cases, were the .next()
> allocation optimized out via a spec revision and *very trivial* change
> to current implementations, the performance would be great. The
> bottleneck would go away. This is much, much easier than having to
> introduce sophisticated escape analysis & allocation removal into JS
> VMs.
>
> This is something that can be solved at the VM level. VMs perform much much
> smarter optimizations than this already. There is no reason to sacrifice
> code correctness and the principle of least astonishment in order to get
> acceptable performance. Benchmarking against "proof of concept"
> implementations is counter-productive in my opinion. The engines are already
> 'allowed' to use the same object when there is no observable difference.
> Even if we allow this 'optimization' it will take the engines as much time
> to implement it so there is no gain from this anyway.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Benjamin (Inglor) Gruenbaum
On Sun, Feb 15, 2015 at 3:06 PM, Katelyn Gadd  wrote:

> In my testing Map and Set are outperformed by a trivial Object or
> Array based data structure in every case, *despite the fact* that
> using an Object as a Map requires the use of Object.keys() to be able
> to sequentially iterate elements. The cost of iterator.next() in v8
> and spidermonkey is currently extremely profound and profiling shows
> all the time is being spent in object creation and GC. (To be fair,
> self-hosting of iterations might improve on this some.)
>

Yes, this is of course true simply because iterating Set/Map was not
optimized yet in V8/SpiderMoney since usually features are first
implemented and then optimized. Benchmarking current naive engine
implementations to make conclusions about the spec is a very risky thing to
do. It's entirely possible for engines to optimize this. By the same logic
I could say that `const` has bad performance because how it is currently
implemented as much much slower than `var` in V8.

> I am sure that given some sufficient amount of compiler engineering,
the allocations could be entirely optimized out, but this is far from
a trivial case so odds are it will not happen soon.

Right, I agree with you there it probably won't happen soon. Changing the
spec won't change that fact. Remember that the engine doesn't actually need
to allocate a new object in cases where it can reuse the old one safely
since it's not used anymore - again, this can be solved at the engine level.

> My point is that for my current test cases, were the .next()
allocation optimized out via a spec revision and *very trivial* change
to current implementations, the performance would be great. The
bottleneck would go away. This is much, much easier than having to
introduce sophisticated escape analysis & allocation removal into JS
VMs.

This is something that can be solved at the VM level. VMs perform much much
smarter optimizations than this already. There is no reason to sacrifice
code correctness and the principle of least astonishment in order to get
acceptable performance. Benchmarking against "proof of concept"
implementations is counter-productive in my opinion. The engines are
already 'allowed' to use the same object when there is no observable
difference. Even if we allow this 'optimization' it will take the engines
as much time to implement it so there is no gain from this anyway.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Katelyn Gadd
Replies inline

On 15 February 2015 at 06:16, Benjamin (Inglor) Gruenbaum
 wrote:
>> In my testing (and in my theory, as an absolute) this is a real
> performance defect in the spec and it will make iterators inferior to
> all other forms of sequence iteration, to the extent that they may end
> up being used very rarely, and developers will be biased away from Map
> and Set as a result.
>
> Why?

To quote my original message:

In my testing Map and Set are outperformed by a trivial Object or
Array based data structure in every case, *despite the fact* that
using an Object as a Map requires the use of Object.keys() to be able
to sequentially iterate elements. The cost of iterator.next() in v8
and spidermonkey is currently extremely profound and profiling shows
all the time is being spent in object creation and GC. (To be fair,
self-hosting of iterations might improve on this some.)


To make this clearer: I have an existing dictionary container based on
Object and Object.keys. Replacing this with Map and Map iterator
produced a slowdown, and profiles showed almost all the time was being
spent in result object creation and GC.

>
> Allocating a new object isn't really expensive, in cases it is and it
> introduces GC pressure a clever engine can optimize it away by not really
> allocating a new object where it is not required. Your suggestion can be
> fully implemented by the engine already in the cases you speak of (where no
> reference is kept) so there is no real speed benefit from it performance
> wise. However in the case an iteration result is kept for later use this can
> be destructive and create unpredictable results.

It's expensive. In general object allocation & GCs show up in profiles
for almost every performance-sensitive application I work on. I'm sure
there are applications where this is not the case, though.
Also, to quote my original message:

I think that past APIs with this problem (for example TypedArray.set)
have proven that 'a sufficiently smart VM can optimize this' is not
representative of real VMs or real use cases.


I am sure that given some sufficient amount of compiler engineering,
the allocations could be entirely optimized out, but this is far from
a trivial case so odds are it will not happen soon.

>
> Also - of course for... of and iterating iterators right now is slower than
> iterating in ways that have been there for years. Modern JS engines usually
> add support for features and only then optimize them.

My point is that for my current test cases, were the .next()
allocation optimized out via a spec revision and *very trivial* change
to current implementations, the performance would be great. The
bottleneck would go away. This is much, much easier than having to
introduce sophisticated escape analysis & allocation removal into JS
VMs.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Subject: Performance of iterator .next() as specified

2015-02-15 Thread Benjamin (Inglor) Gruenbaum
> In my testing (and in my theory, as an absolute) this is a real
performance defect in the spec and it will make iterators inferior to
all other forms of sequence iteration, to the extent that they may end
up being used very rarely, and developers will be biased away from Map
and Set as a result.

Why?

Allocating a new object isn't really expensive, in cases it is and it
introduces GC pressure a clever engine can optimize it away by not really
allocating a new object where it is not required. Your suggestion can be
fully implemented by the engine already in the cases you speak of (where no
reference is kept) so there is no real speed benefit from it performance
wise. However in the case an iteration result is kept for later use this
can be destructive and create unpredictable results.

Also - of course for... of and iterating iterators right now is slower than
iterating in ways that have been there for years. Modern JS engines usually
add support for features and only then optimize them.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Performance of iterator .next() as specified

2015-02-15 Thread Katelyn Gadd
I'm certainly in favor of VMs improving to handle that, and adding
pressure for it is good. However, optimizing a TypedArray temporary
arg to .set() is a much simpler problem than doing the escape analysis
necessary to be certain a .next() result doesn't escape from a calling
scope and isn't used after a later next() call. Applying pressure will
be a good way to make sure VM authors do the work necessary for this
to happen, but if iterators are unacceptably slow in shipping
implementations for a year+ I think the odds are good that most
shipping software will avoid using them, at which point VM authors
will have no reason to optimize for primitives nobody uses. =[

The fixed layout of the iterator object would allow the GC to allocate
it cheaply and in the case of values (like ints) it wouldn't need to
trace it either - so that helps a lot. But I don't know how realistic
those optimizations are in practice.

On 15 February 2015 at 02:36, Andrea Giammarchi
 wrote:
> +1 and I've raised same concerns 2 years ago [1]
>
> IIRC the outcome was that VM should be good enough to handle objects with
> very short lifecycle, I'm still convinced (behind tests) that generators are
> overkill for IoT devices (low clock and way lower RAM).
>
> Having always same object per iteration makes sense to me at least until
> it's done so that could be just a struct-like `{done: false, value: null}`
> object and GC will be happier than ever.
>
> Regards
>
>
> [1]
> http://webreflection.blogspot.co.uk/2013/06/on-harmony-javascript-generators.html
>
> On Sun, Feb 15, 2015 at 10:06 AM, Katelyn Gadd  wrote:
>>
>> As specified, iterator .next() seems to be required to return a new
>> object instance for each iteration.
>>
>> In my testing (and in my theory, as an absolute) this is a real
>> performance defect in the spec and it will make iterators inferior to
>> all other forms of sequence iteration, to the extent that they may end
>> up being used very rarely, and developers will be biased away from Map
>> and Set as a result.
>>
>> The issue here is that the new object requirement means that every
>> iteration produces GC pressure. I think that past APIs with this
>> problem (for example TypedArray.set) have proven that 'a sufficiently
>> smart VM can optimize this' is not representative of real VMs or real
>> use cases.
>>
>> In the specific case of .next(), the method returning a new object on
>> every iteration does not produce any actual improvement to usability:
>> There is no realistic use case that requires saving multiple next()
>> results from the same sequence, as the sequence itself represents (at
>> least in most cases) a container or generated value sequence that is
>> fully reproducible on demand.
>>
>> I think allowing (or requiring) implementations to return the same
>> object instance from every .next() call, or perhaps as a usability
>> compromise, reusing a pair of objects on a round-robin basis (so that
>> you can keep around the current and prior result) would be a very good
>> decision here.
>>
>> In my testing Map and Set are outperformed by a trivial Object or
>> Array based data structure in every case, *despite the fact* that
>> using an Object as a Map requires the use of Object.keys() to be able
>> to sequentially iterate elements. The cost of iterator.next() in v8
>> and spidermonkey is currently extremely profound and profiling shows
>> all the time is being spent in object creation and GC. (To be fair,
>> self-hosting of iterations might improve on this some.)
>>
>> Oddly enough, I consider the ES iterator spec to be a big improvement
>> over C#'s IEnumerable, in terms of usability/API. But this is an area
>> where it is intrinsically worse performance-wise than IEnumerable and
>> that's unfortunate.
>>
>> -kg
>> ___
>> 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: Performance of iterator .next() as specified

2015-02-15 Thread Andrea Giammarchi
+1 and I've raised same concerns 2 years ago [1]

IIRC the outcome was that VM should be good enough to handle objects with
very short lifecycle, I'm still convinced (behind tests) that generators
are overkill for IoT devices (low clock and way lower RAM).

Having always same object per iteration makes sense to me at least until
it's done so that could be just a struct-like `{done: false, value: null}`
object and GC will be happier than ever.

Regards


[1]
http://webreflection.blogspot.co.uk/2013/06/on-harmony-javascript-generators.html

On Sun, Feb 15, 2015 at 10:06 AM, Katelyn Gadd  wrote:

> As specified, iterator .next() seems to be required to return a new
> object instance for each iteration.
>
> In my testing (and in my theory, as an absolute) this is a real
> performance defect in the spec and it will make iterators inferior to
> all other forms of sequence iteration, to the extent that they may end
> up being used very rarely, and developers will be biased away from Map
> and Set as a result.
>
> The issue here is that the new object requirement means that every
> iteration produces GC pressure. I think that past APIs with this
> problem (for example TypedArray.set) have proven that 'a sufficiently
> smart VM can optimize this' is not representative of real VMs or real
> use cases.
>
> In the specific case of .next(), the method returning a new object on
> every iteration does not produce any actual improvement to usability:
> There is no realistic use case that requires saving multiple next()
> results from the same sequence, as the sequence itself represents (at
> least in most cases) a container or generated value sequence that is
> fully reproducible on demand.
>
> I think allowing (or requiring) implementations to return the same
> object instance from every .next() call, or perhaps as a usability
> compromise, reusing a pair of objects on a round-robin basis (so that
> you can keep around the current and prior result) would be a very good
> decision here.
>
> In my testing Map and Set are outperformed by a trivial Object or
> Array based data structure in every case, *despite the fact* that
> using an Object as a Map requires the use of Object.keys() to be able
> to sequentially iterate elements. The cost of iterator.next() in v8
> and spidermonkey is currently extremely profound and profiling shows
> all the time is being spent in object creation and GC. (To be fair,
> self-hosting of iterations might improve on this some.)
>
> Oddly enough, I consider the ES iterator spec to be a big improvement
> over C#'s IEnumerable, in terms of usability/API. But this is an area
> where it is intrinsically worse performance-wise than IEnumerable and
> that's unfortunate.
>
> -kg
> ___
> 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: TemplateLiteral tagged with super

2015-02-15 Thread Shinji Ikari
That case we can simply allow TemplateLiteral in Arguments. It will become
more consistent as well and causes less cognitive burden. We don't even
need to define MemberExpressionTemplateLiteral and CallExpression
TemplateLiteral any more. BTW, the only places where Arguments is referred
to are MemberExpression, CallExpression, and SuperCall.

Although it will be a rather breaking change because it will change the
precedence of expressions. For example, currently new a`x` is a
NewExpression. a`x` will be evaluated first. But with this change, it will
also be a simple MemberExpression. The a method will be [[Construct]] ed
with "x" as arg.

On Fri, Feb 13, 2015 at 8:01 PM, Gary Guo  wrote:

> If super TemplateLiteral is added, I will suggest we add new
> MemberExpression TemplateLiteral, which might be more useful in practice.
>
> --
> Date: Fri, 13 Feb 2015 20:55:49 -0500
> Subject: Re: TemplateLiteral tagged with super
> From: zenpars...@gmail.com
> To: al...@wirfs-brock.com
> CC: es-discuss@mozilla.org
>
>
> > But what would it be good for.  Can anybody think of a practical use
> case for this?
>
> I can't.  And for what it's worth I didn't find *any* semantics obvious. I
> think in general it's best to limit the contexts in which super can occur,
> since it has different meanings depending on context.
>
> Seems like a "defer" thing to me.
>
> ___ 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
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Performance of iterator .next() as specified

2015-02-15 Thread Katelyn Gadd
As specified, iterator .next() seems to be required to return a new
object instance for each iteration.

In my testing (and in my theory, as an absolute) this is a real
performance defect in the spec and it will make iterators inferior to
all other forms of sequence iteration, to the extent that they may end
up being used very rarely, and developers will be biased away from Map
and Set as a result.

The issue here is that the new object requirement means that every
iteration produces GC pressure. I think that past APIs with this
problem (for example TypedArray.set) have proven that 'a sufficiently
smart VM can optimize this' is not representative of real VMs or real
use cases.

In the specific case of .next(), the method returning a new object on
every iteration does not produce any actual improvement to usability:
There is no realistic use case that requires saving multiple next()
results from the same sequence, as the sequence itself represents (at
least in most cases) a container or generated value sequence that is
fully reproducible on demand.

I think allowing (or requiring) implementations to return the same
object instance from every .next() call, or perhaps as a usability
compromise, reusing a pair of objects on a round-robin basis (so that
you can keep around the current and prior result) would be a very good
decision here.

In my testing Map and Set are outperformed by a trivial Object or
Array based data structure in every case, *despite the fact* that
using an Object as a Map requires the use of Object.keys() to be able
to sequentially iterate elements. The cost of iterator.next() in v8
and spidermonkey is currently extremely profound and profiling shows
all the time is being spent in object creation and GC. (To be fair,
self-hosting of iterations might improve on this some.)

Oddly enough, I consider the ES iterator spec to be a big improvement
over C#'s IEnumerable, in terms of usability/API. But this is an area
where it is intrinsically worse performance-wise than IEnumerable and
that's unfortunate.

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


Re: Proposal: No LineTerminator should be allowed between {CallExpression, MemberExpression} TemplateLiteral

2015-02-15 Thread Shinji Ikari
The difference is the uncommon delimiter of the argument lists. If the
template literal must be surrounded by a pair of parentheses it will become
more visually significant. Since it's not, I think not allowing the line
terminator is reasonable.

On Sat, Feb 14, 2015 at 1:41 PM, Shinji Ikari  wrote:

> Ah yes! I will resend.
>
> On Fri, Feb 13, 2015 at 20:54 Kevin Smith  wrote:
>
>> Hey there!  Did you mean to reply to the list?
>>
>> On Fri, Feb 13, 2015 at 11:53 PM, Shinji Ikari 
>> wrote:
>>
>>> The difference is the uncommon delimiter of the argument lists. If the
>>> template literal must be surrounded by a pair of parentheses it will become
>>> more visually significant. Since it's not, I think not allowing the line
>>> terminator is reasonable.
>>>
>>> On Fri, Feb 13, 2015 at 20:29 Kevin Smith  wrote:
>>>

> I propose we add a [No LineTerminator here] between CallExpression/
> MemberExpression and TemplateLiteral.
>

 This would be inconsistent, since there are no such restrictions
 between member expression or call expression components otherwise.  For
 example, in:

 foo
 (bar)

 and

 foo
 [bar]

 there is no semicolon insertion.


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