Re: Analog to Object.getPropertyDescriptor() for *changing* a property value?

2011-06-21 Thread Brendan Eich
On Jun 21, 2011, at 1:50 PM, Axel Rauschmayer wrote:

> That sounds like the opposite argument you are making with regard to the 
> hypothetical |here|:
> 
>> BTW I do not agree we can or should try to reserve 'here' or expose the 
>> method's "home object" -- that breaks abstractions built using prototypes. 
>> 'super' does not, because it always goes to the [[Prototype]] of the object 
>> in which the method was defined.

No, the arguments are close cousins, in no way opposed.

You should not in general mutate shared prototype state via one of N delegating 
objects. It leads to trouble.

You should not depend on which of M prototype objects along the chain holds a 
method. Similar trouble with scaling M, evolving the program to increase M by 
interposing a new prototype which might inject a shadowing method for good 
reason, and so on.


> The prototype seems to be the best location for shared data (such as the 
> number of instances of a class).

Counting instances can't be done without leaking GC non-determinsm, so this is 
a bogus example. Can you come up with another? Shared mutable state in 
prototypes that is visibly mutable by means of a reference to one of N 
delegating objects  is usually a bug.

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


Re: Making "super" work outside a literal?

2011-06-21 Thread Brendan Eich
On Jun 21, 2011, at 11:53 AM, Brendan Eich wrote:

> On Jun 21, 2011, at 11:33 AM, Oliver Hunt wrote:
> 
>> I'm answering some of the performance questions in this, but i don't know 
>> what the intended semantics of 'dynamic super' would be so I can't give 
>> specific details of most of the use cases.  If it's essentially sugar for 
>> super.foo => Object.getPrototypeOf(this).foo (with appropriate munging for 
>> calls, etc) then the cost is at point of use only, but if it's anything more 
>> fun (there are references to additional implicit parameters below which 
>> would be fairly bad for performance of calls)
> 
> That's the point: super must mean something other than 
> Object.getPrototypeOf(this). Otherwise with the prototypal pattern you will 
> infinitely recurse calling the same prototype-homed foo from foo via 
> super.foo().

Example:

C.prototype = {
  foo() { addedValue(); return super.foo(); }
  ...
};

x = new C;
x.foo();   // oops, diverges in endless self-recursion.


Now, with the static 'super' semantics plus Object.defineMethod(O, 'foo', 
C.prototype.foo), you can rebind 'super'.

One thing I'm not sure about: whether Object.defineMethod should mutate 
C.prototype.foo's internal property, or make a new function object with a 
different 'super' binding.

In any case, the static and internal-to-method semantics avoid the infinite 
recursion hazard, and they avoid the cost of an extra parameter beyond |this|.

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


Re: Analog to Object.getPropertyDescriptor() for *changing* a property value?

2011-06-21 Thread Axel Rauschmayer
That sounds like the opposite argument you are making with regard to the 
hypothetical |here|:

> BTW I do not agree we can or should try to reserve 'here' or expose the 
> method's "home object" -- that breaks abstractions built using prototypes. 
> 'super' does not, because it always goes to the [[Prototype]] of the object 
> in which the method was defined.

The prototype seems to be the best location for shared data (such as the number 
of instances of a class). Wouldn’t you also want to abstract from the exact 
location of such a property?

I find that Common Lisp does this well, via "places":
- Property lookup => returns a place, e.g. a pair (object, property name)
- Use the place to either read the property value or to change it.

Can’t comment on Proxies, though.

On Jun 21, 2011, at 21:36 , Brendan Eich wrote:

> On Jun 21, 2011, at 8:24 AM, Axel Rauschmayer wrote:
> 
>> As a loose analog to the prototype-chain-traversing getPropertyDescriptor(), 
>> I would still like to have something that allows one to easily *change* 
>> properties higher up the prototype chain (e.g. to use a prototype to share 
>> state).
> 
> Such mutation from a delegating object, because it affects all other objects 
> that delegate to the shared prototype, is usually a bug! Shared mutables are 
> a bitch, even ignoring threads.
> 
> I think it would be better to require the mutation to have a direct reference 
> to the prototype. Yes, it could be discovered via Object.getPrototypeOf -- 
> assuming no proxies.
> 
> We cannot assume no proxies, and a Proxy is responsible for delegating to 
> possibly hidden objects other than the |proto| passed to Proxy.create.
> 
> Even without proxies, or assuming they behave like native objects, mutation 
> from one of N delegating objects is an anti-pattern.
> 
> /be
> 
> 
>> 
>> Maybe it would be enough to just have Object.getDefiningObject(obj, 
>> propName):
>> http://www.mail-archive.com/es-discuss@mozilla.org/msg06652.html
>> 
>> But I can also imagine syntactic sugar:
>>   obj.foo := "abc"
>> desugars to
>>   Object.getDefiningObject(obj, "foo").foo = "abc"
>> 
>> -- 
>> Dr. Axel Rauschmayer
>> 
>> a...@rauschma.de
>> twitter.com/rauschma
>> 
>> home: rauschma.de
>> blog: 2ality.com
>> 
>> 
>> 
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
> 

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: Analog to Object.getPropertyDescriptor() for *changing* a property value?

2011-06-21 Thread Brendan Eich
On Jun 21, 2011, at 8:24 AM, Axel Rauschmayer wrote:

> As a loose analog to the prototype-chain-traversing getPropertyDescriptor(), 
> I would still like to have something that allows one to easily *change* 
> properties higher up the prototype chain (e.g. to use a prototype to share 
> state).

Such mutation from a delegating object, because it affects all other objects 
that delegate to the shared prototype, is usually a bug! Shared mutables are a 
bitch, even ignoring threads.

I think it would be better to require the mutation to have a direct reference 
to the prototype. Yes, it could be discovered via Object.getPrototypeOf -- 
assuming no proxies.

We cannot assume no proxies, and a Proxy is responsible for delegating to 
possibly hidden objects other than the |proto| passed to Proxy.create.

Even without proxies, or assuming they behave like native objects, mutation 
from one of N delegating objects is an anti-pattern.

/be


> 
> Maybe it would be enough to just have Object.getDefiningObject(obj, propName):
> http://www.mail-archive.com/es-discuss@mozilla.org/msg06652.html
> 
> But I can also imagine syntactic sugar:
>obj.foo := "abc"
> desugars to
>Object.getDefiningObject(obj, "foo").foo = "abc"
> 
> -- 
> Dr. Axel Rauschmayer
> 
> a...@rauschma.de
> twitter.com/rauschma
> 
> home: rauschma.de
> blog: 2ality.com
> 
> 
> 
> ___
> 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: [Harmony proxies] Non-configurable properties: fixed properties VS trap all with invariants enforcement

2011-06-21 Thread Tom Van Cutsem
Yes, you made a nice case. In a way I'm glad, as I wasn't too keen on the
additional complexity brought about by the bicephal approach (membranes
could still be made to work by converting all non-configurable properties
into accessors as shown on the wiki page, at the price of giving up fully
transparent wrappers)

I guess the way forward is to try and specify precisely what consistency
checks a proxy should perform, and how cheap or costly these will turn out
to be.

Re. untrusted code communicating via non-configurable, writable properties:
I believe this is not a problem specific to proxies with fixed properties,
or even proxies in general. As soon as you share a non-frozen object, this
kind of communication can happen. But granted: membrane proxies +
transparent fixed properties are flawed in this regard.

Cheers,
Tom

2011/6/20 Mark S. Miller 

> Hi David, my compliments. This is an important issue I should have caught
> but didn't notice. Thanks. I think agree with your conclusion (which I was
> leaning towards anyway).
>
>
> On Mon, Jun 20, 2011 at 10:25 AM, David Bruant wrote:
>
>> Le 20/06/2011 17:15, David Bruant a écrit :
>> > Hi,
>> >
>> > We may need to switch from the (bicephal) fixed properties model to a
>> > "trap all with invariants enforcement" model.
>> >
>> > With the current simple membrane example:
>> > -
>> > var o = {};
>> > var s = makeSimpleMembrane(o);
>> > var wrapper = s.wrapper,
>> > gate = s.gate;
>> >
>> > // ... later, in untrusted code (variable name kept for readability)
>> > Object.defineProperty(wrapper, 'a', {value:1, configurable:false});
>> >
>> >
>> > // ... later, back in trusted code:
>> > gate.disable()
>> >
>> >
>> > // ... later in the same untrusted code which had a reference to the
>> > wrapper object.
>> Actually, it's more convincing if the wrapper is given to another piece
>> of untrusted code, because this code should not have access to what
>> another untrusted code added to the wrapper AFTER disabling. Also,
>> untrusted code could communicate through non-configurable, but writable
>> properties which doesn't sounds good.
>>
>> > wrapper.a; // 1 in the fixed properties model
>> > // throw if the 'get' traps was actually called.
>> > // Such a difference is certainly noticeable in all traps.
>> > -
>> >
>> > The problem with the fixed property model is that properties exist on
>> > the proxy object itself with no way to control (and prevent in our
>> > case) access to them.
>> >
>> > David
>> > ___
>> > 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
>>
>
>
>
> --
> 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: this vs thi\u0073

2011-06-21 Thread Mike Samuel
2011/6/21 Brendan Eich :
> I think some engines just have a bug to fix here, nothing more. :-/

I think the spec could be clearer as to whether "but not ReservedWord"
applies before or after the IdentifierName is decoded.

I'm happy to file bugs if people tell me what the bug is?

Is it

(A) Not treating reserved words with characters
escaped where an Identifier is expected as a
syntax error.

var \u0069\u0066

should be a syntax error.

(B) Not distinguishing identifiers whose decoded
IdentifierName is a reserved word as distinct
from the keywod.

eval("var thi\\u0073; this !== thi\\u0073")

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


Re: this vs thi\u0073

2011-06-21 Thread Brendan Eich
I think some engines just have a bug to fix here, nothing more. :-/

/be

On Jun 21, 2011, at 11:48 AM, Mike Samuel wrote:

> 2011/6/21 Mike Samuel :
>> In that case, we still have at least 3 (haven't tested IE) of 4 major
>> browsers agreeing that the illegal EcmaScript program
>> 
>>this.\u0069\u0066 = function () { alert("called \u0069\u0066"); };
>> 
>>\u0069\u0066(false)
>>alert(1);
>> 
>> should be interpreted as a call via the reference "if" followed by a
>> call via the reference "alert".
> 
> I tested on IE 7 and IE 8 and they both reject the above.
> ___
> 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: Making "super" work outside a literal?

2011-06-21 Thread Brendan Eich
On Jun 21, 2011, at 11:33 AM, Oliver Hunt wrote:

> I'm answering some of the performance questions in this, but i don't know 
> what the intended semantics of 'dynamic super' would be so I can't give 
> specific details of most of the use cases.  If it's essentially sugar for 
> super.foo => Object.getPrototypeOf(this).foo (with appropriate munging for 
> calls, etc) then the cost is at point of use only, but if it's anything more 
> fun (there are references to additional implicit parameters below which would 
> be fairly bad for performance of calls)

That's the point: super must mean something other than 
Object.getPrototypeOf(this). Otherwise with the prototypal pattern you will 
infinitely recurse calling the same prototype-homed foo from foo via 
super.foo().

If super was shorthand only for Object.getPrototypeOf(this), then there's 
hardly any point in making super short for that expression.

Axel's notion of a |here| object helps, in that Object.getPrototypeOf(here) is 
more what you want from 'super' -- but not necessarily when the method has been 
borrowed by another object used as |here|. Note the "necessarily" -- you may 
know how to rebind 'super', but you may not. Allen's Object.defineMethod 
requires an affirmative defense before you can rebind super. It's a safety 
step, since 'super' is an internal function property and *not* a free parameter.

BTW I do not agree we can or should try to reserve 'here' or expose the 
method's "home object" -- that breaks abstractions built using prototypes. 
'super' does not, because it always goes to the [[Prototype]] of the object in 
which the method was defined.

/be

> 
> On Jun 21, 2011, at 11:04 AM, Sean Eagan wrote:
>> I disagree that a dynamic super would lead to a '50% increase in
> 
>> argument passing overhead, on average'.  First, there is the implicit
>> 'arguments' argument, which is an object that actually needs to be
>> created per call site, not just a binding, and thus is presumably much
>> more expensive.
> Nope, creating an arguments object is on average free, as most uses can be 
> lowered.
> 
>> Second, 'argument passing overhead' involves sunk
>> costs that are not dependent on the number of argument bindings that
>> need to be created.
> Every additional argument has a performance cost
> 
>> Third, implicit arguments, as 'super' would be,
>> should be less costly than explicit arguments since the argument value
>> does not need to be resolved.
> 
> I haven't really been following this but why does super need to be passed as 
> an additional parameter?
> 
>> 
>> A better estimate of the overhead of dynamic super would probably be
>> the overhead of an implicit 'this' binding, i.e. the cost of creating
>> a 'this' binding for a function activation that not involving an
>> explicit 'this' via Function.prototype.call or
>> Function.prototype.apply, or Function.prototype.bind.  Does anyone
>> have any estimates of this cost, either absolute or relative to some
>> other cost?
> 
> That depends on the exact use case.  JSC doesn't determine what |this| is at 
> the callsite (In general strict mode makes that impossible), so it becomes a 
> question of whether you use it or not.
> 
>> I was unaware that dynamic super had been discussed, proposed, or
>> attempted previously for ES, or that it was ever included to have
>> 'pervasive overhead'.  Do you any references for this?
> 
> No idea -- it would depend on what the actual semantics of super were
> 

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


Re: this vs thi\u0073

2011-06-21 Thread Mike Samuel
2011/6/21 Mike Samuel :
> In that case, we still have at least 3 (haven't tested IE) of 4 major
> browsers agreeing that the illegal EcmaScript program
>
>    this.\u0069\u0066 = function () { alert("called \u0069\u0066"); };
>
>    \u0069\u0066(false)
>    alert(1);
>
> should be interpreted as a call via the reference "if" followed by a
> call via the reference "alert".

I tested on IE 7 and IE 8 and they both reject the above.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: A shorthand for Object.defineProperty?

2011-06-21 Thread Axel Rauschmayer
>> This would make things easier to understand. When I explain this aspect of 
>> JavaScript to others, they are often stumped, but I have never encountered 
>> anyone who was confused by Python:
>> class MyClass:
>> def mymethod(self):
>> return "hello world"
>> def myfunction():
>> return "hello world"
>> 
>> So this is probably my real point: can we make things as un-confusing as in 
>> Python?
> 
> Python has its confusing parts too.

Yes, I only meant when it comes to functions versus methods.

> Explaining things to beginners still will involve explaining 'function' 
> (long-form) syntax for the foreseeable future, so you don't gain anything by 
> crippling arrow syntax.
> 
> But once beginners learn more, they will hate having to write out the long 
> form for all the dynamic this cases that can't be written using 
> method-in-initialiser syntax.


Agreed. If a simplification could be done naturally, that would be great. But 
as that seems impossible, forcing things does not make sense.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: Making "super" work outside a literal?

2011-06-21 Thread Oliver Hunt
I'm answering some of the performance questions in this, but i don't know what 
the intended semantics of 'dynamic super' would be so I can't give specific 
details of most of the use cases.  If it's essentially sugar for super.foo => 
Object.getPrototypeOf(this).foo (with appropriate munging for calls, etc) then 
the cost is at point of use only, but if it's anything more fun (there are 
references to additional implicit parameters below which would be fairly bad 
for performance of calls)

On Jun 21, 2011, at 11:04 AM, Sean Eagan wrote:
> I disagree that a dynamic super would lead to a '50% increase in

> argument passing overhead, on average'.  First, there is the implicit
> 'arguments' argument, which is an object that actually needs to be
> created per call site, not just a binding, and thus is presumably much
> more expensive.
Nope, creating an arguments object is on average free, as most uses can be 
lowered.

>  Second, 'argument passing overhead' involves sunk
> costs that are not dependent on the number of argument bindings that
> need to be created.
Every additional argument has a performance cost

>  Third, implicit arguments, as 'super' would be,
> should be less costly than explicit arguments since the argument value
> does not need to be resolved.

I haven't really been following this but why does super need to be passed as an 
additional parameter?

> 
> A better estimate of the overhead of dynamic super would probably be
> the overhead of an implicit 'this' binding, i.e. the cost of creating
> a 'this' binding for a function activation that not involving an
> explicit 'this' via Function.prototype.call or
> Function.prototype.apply, or Function.prototype.bind.  Does anyone
> have any estimates of this cost, either absolute or relative to some
> other cost?

That depends on the exact use case.  JSC doesn't determine what |this| is at 
the callsite (In general strict mode makes that impossible), so it becomes a 
question of whether you use it or not.

> I was unaware that dynamic super had been discussed, proposed, or
> attempted previously for ES, or that it was ever included to have
> 'pervasive overhead'.  Do you any references for this?

No idea -- it would depend on what the actual semantics of super were

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


Re: A shorthand for Object.defineProperty?

2011-06-21 Thread Brendan Eich
On Jun 21, 2011, at 2:18 AM, Axel Rauschmayer wrote:

> Do we really need the dynamic this arrow ->, or can we make do with just 
> the lexical this arrow =>.
>>> Are functions that depend on dynamic |this| ever *not* methods?
>> 
>> Sure. The main use-case is constructors (and you can make a function do 
>> double-duty, as a constructor or a function called without 'new').
> 
> With classes, constructors will become methods, right?

Not in the sense we were discussing, where you could call new o.C or else o.C().

Yes, C.prototype.constructor === C, but people don't write "x = new C; y = new 
x.constructor" much. You can, that is possible in JS today without classes.

Again, classes are sugar for the prototypal pattern. They don't add anything 
different or magic about how the constructor and the prototype reference each 
other.


>> Also, some times, people write functions not used as methods but called via 
>> .call or .apply. It happens.
> 
> Wouldn’t it be better to have lexical |this| in these cases, so that 
> foo.call(null, ...) does not affect |this|?

No, the .call and .apply cases I cited, which intentionally pass varying 
(dynamic) objects as the first argument, need that first argument to bind to 
the |this| parameter.


>>> Wouldn’t you always want to use an object literal for methods, especially 
>>> if some features (such as |super|) depend on it?
>> 
>> Probably. But so what?
>> 
>> We're not making mandatory syntax either way with function, so why should we 
>> with arrow?
> 
> Old-style functions would be rarely used and there would be a clear 
> separation of concerns:
> - Want a method? Use an object literal.

That's too restrictive. JS allows the Google Closure style of assigning methods 
via C.prototype.m1 = function.., etc.


> - Want a function that is not a method (i.e., lexical this)? Use an arrow 
> function with =>

I think you are trying to restrict JS users in ways they won't like. Anyway, we 
can't make an incompatible change to functions. Arrows as proposed are just 
syntax for functions, including with |this| bound lexically.

If we make arrows restrictive in ways that functions (with either dynamic or 
lexical this-binding) are not restricted, we're essentially telling some JS 
programmers that they're "doing something wrong" or "using forms that are hard 
to understand for beginners".

Sorry, there's no evidence for such claims, and without such evidence, it's not 
a good idea for TC39 to put itself in such a "restrictionist" position.

(Contrast this with 'with', dynamic eval var injection, and other things banned 
by strict mode where lexical scope, capability leaks, and optimizability were 
all destroyed by the banned forms.)


> This would make things easier to understand. When I explain this aspect of 
> JavaScript to others, they are often stumped, but I have never encountered 
> anyone who was confused by Python:
> class MyClass:
> def mymethod(self):
> return "hello world"
> def myfunction():
> return "hello world"
> 
> So this is probably my real point: can we make things as un-confusing as in 
> Python?

Python has its confusing parts too.

Anyway, if you are talking about making classes less confusing, that's a fine 
goal for classes.

But shorter function syntax needs to be shorter without requiring only "lexical 
this", given all the "dynamic this" use-cases including methods assigned as in 
Google Closure. Functions are used in several ways in JS and the overlong 
syntax (both 'function' and 'return') are a problem for several of the 
use-cases.

Method syntax as specified for Harmony inside object literals *does* have 
dynamc this-binding. There's no dispute about that.


>>> Maybe I just like the distinction introduced by block lambdas too much:
>>> - dynamic this --> existing functions and methods
>>> - lexical this --> new, more compact construct, mainly used as the argument 
>>> of functions and methods.
>> 
>> Block-lambdas are not arrows. Arrows are just syntax and try to shorten 
>> function usage in general (including the .bind or var self=this; idiom). 
>> Block-lambdas must preserve Tennent's Correspondence Principle, so they have 
>> no choice but to treat |this| lexically.
> 
> I know. But block-lambdas enforce a separation of concerns (because they have 
> no choice, really) that I would like short-syntax functions (arrows or not) 
> to enforce, as well.

That's nice for the use-cases that want lexical-this. For dynamic-this, it's a 
usability burden without justification.

Explaining things to beginners still will involve explaining 'function' 
(long-form) syntax for the foreseeable future, so you don't gain anything by 
crippling arrow syntax.

But once beginners learn more, they will hate having to write out the long form 
for all the dynamic this cases that can't be written using 
method-in-initialiser syntax.


>>> This distinction works well as a rule of thumb and keeps things easy to 
>>> explain.
>> 
>> It's not 

Re: imperative vs functional APIs or: how to work with constant objects?

2011-06-21 Thread Mark S. Miller
On Tue, Jun 21, 2011 at 9:47 AM, Claus Reinke wrote:

> Javascript data structure operations: some of the APIs are imperative, some
> are functional, some are mixed. Having functional equivalents
> to all imperative data structure operations is necessary to support
> expression-oriented programming over constant data structures.
>
> "imperative" here refers to operations that are designed to be used as
> statements, changing inputs by side-effect, while "functional" refers to
> operations designed to be used as expressions, leaving their inputs
> unchanged. A familiar example is the Array API, e.g.:
>
>   array.concat([1])- returns a modified copy of array, expression
>
>   array.push(1)- modifies array in place, "statement"
>
> It does seem as if older API elements tend to be imperative while newer
> ones tend to be functional. However, not all imperative
> operations have functional counterparts yet, and with increasing
> focus on constant and frozen objects, the need for functional
> operations is going to increase.
>
> In particular, I have been wondering about how freezing objects
> curtails what I am able to do with them. Having worked with pure
> functional language for a long time, I really like the advantages of
> frozen/constant objects, both for avoiding bugs and to enable
> optimizations, but I'm not used to not having a full set of operations to
> work with such objects:
>
> Example 1: constant functions, prototypes and toString
>
>   The standard API for functions requires imperative operations
>   for both prototypical inheritance and for string representation.
>
>   const C() {}
>   // C.prototype.toString = function() { return 'C()' }
>   // C.toString = function() { return 'C()' }
>
> Example 2: property update
>
>   The standard API for object property update is imperative.
>
>   const obj = Object.freeze({ age : 1, .. });
>   const older_obj = // a modified copy of obj, with age : 2??
>

 Hi Claus, interesting idea. Given

 The idea of {x: a, y: b, ...: c} – record extension and row
capture
–
for structuring and destructuring comes to mind, but ES objects are a
different animal compared to ML records. For example, which properties of c are
copied into the object being initialized by {x: a, y: b, ...: c}?
enumerable? own? etc.

(from )

you could say

const older_obj = { age: 2, ...: obj };

But as the note says, there are a bunch of open questions that need to be
settled before this becomes a serious candidate. We should examine how this
interacts with other aspects of extended object literals.


>
> The standard APIs for these fundamental operations are imperative
> and so are not available on frozen objects (this also applies to the
> record strawman, for instance).
>
> How does one achieve the effects of these operations on frozen
> objects, by creating modified copies? For an expression-oriented style of
> programming where no object is ever modified in place, it seems one has to
> use a lower level API, perhaps by calling
> Object.create and Object.freeze to implement some form of
> Object.clone, then mixing in the update on the clone before freezing it. Or
> perhaps using proxies to achieve the effect..
>
> The situation is somewhat similar to the declarative object initializers
> being worked on as object literal extensions, but those don't seem to help
> here.
>
> What is the best way of doing functional/declarative/**expression-
> oriented object modification in ES5 or ES/next? Is there really an
> imperative-preferred flaw in the current design?
>
> Claus
>
>
> __**_
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/**listinfo/es-discuss
>



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


Re: this vs thi\u0073

2011-06-21 Thread Mike Samuel
2011/6/21 Allen Wirfs-Brock :
> ES5.1:
>
> 7.6.1   Reserved Words
>
> A reserved word is an IdentifierName that cannot be used as an Identifier.
>
> 7.6    Identifier Names and Identifiers
>
> Identifier Names are tokens that are interpreted according to the grammar
> given in the “Identifiers” section of chapter 5 of the Unicode standard,
> with some small modifications. An Identifier is an IdentifierName that is
> not a ReservedWord (see 7.6.1). The Unicode identifier grammar is based on
> both normative and informative character categories specified by the Unicode
> Standard. The characters in the specified categories in version 3.0 of the
> Unicode standard must be treated as in those categories by all conforming
> ECMAScript implementations.
>
> This standard specifies specific character additions: The dollar sign ($)
> and the underscore (_) are permitted anywhere in an IdentifierName.
>
> Unicode escape sequences are also permitted in an IdentifierName, where they
> contribute a single character to the IdentifierName, as computed by the CV
> of the UnicodeEscapeSequence (see 7.8.4). The \ preceding the
> UnicodeEscapeSequence does not contribute a character to the IdentifierName.
> A UnicodeEscapeSequence cannot be used to put a character into an
> IdentifierName that would otherwise be illegal. In other words, if a \
> UnicodeEscapeSequence sequence were replaced by its UnicodeEscapeSequence's
> CV, the result must still be a valid IdentifierName that has the exact same
> sequence of characters as the original IdentifierName. All interpretations
> of identifiers within this specification are based upon their actual
> characters regardless of whether or not an escape sequence was used to
> contribute any particular characters.
>
> The red text would seems to say that \u0069f and if are the same reserved
> word.
> This may not match implementations but it is what the spec. says.
> ES3 didn't distinguish IdentifierName from Identifier but from a quick scan
> of the ES3 language I don't see that the spec. is any different in this
> regard.
> Also, given the pervasive  substitution of Unicode escape sequences I don't
> see why they shouldn't be legal in reserved words.

"An Identifier is an IdentifierName that is not a ReservedWord (see
7.6.1)" seems to be a non-normative reference to the normative 7.6
production (the "see 7.6.1" is just a reference to the definition of
ReservedWord)

Identifier :: IdentifierName (but not ReservedWord)

Your interpretation assumes that the "but not ReservedWord" language
in the Identifier production applies *after* the identifier has been
decoded but that is not at all clear to me.
From the section you quoted, "Identifier Names are tokens" i.e.
sequences of SourceCharacters, so the token "\u0069f" is clearly
distinct from the token "if".

Since the normative "but nor ReservedWord" appears in a lexical token
grammar it should apply at the token level before any interpretation
happens.

Assuming your interpretation is correct though,
   \u0069f
may be an IdentifierName corresponding to a reserved keyword, but
since IfStatement is defined in terms of

IfStatement : if ( Expression ) Statement else Statement
 if ( Expression ) Statement

where "if" appears literally instead of any reference to an
IdentifierName whose decoded value is "if", would you agree that

   \u0069f(false)
   alert(1);

is not a valid EcmaScript program.  It should definitely not be
interpreted as an EcmaScript program containing an IfStatement.


In that case, we still have at least 3 (haven't tested IE) of 4 major
browsers agreeing that the illegal EcmaScript program

this.\u0069\u0066 = function () { alert("called \u0069\u0066"); };

\u0069\u0066(false)
alert(1);

should be interpreted as a call via the reference "if" followed by a
call via the reference "alert".
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Making "super" work outside a literal?

2011-06-21 Thread Sean Eagan
On Tue, Jun 21, 2011 at 10:51 AM, Allen Wirfs-Brock
 wrote:
>
> On Jun 21, 2011, at 3:28 PM, Sean Eagan wrote:
>
>> On Sun, Jun 19, 2011 at 2:14 PM, Brendan Eich  wrote:
>>> On Jun 19, 2011, at 10:20 AM, Axel Rauschmayer wrote:
>>>
>>> It would be nice if "super" could work in any method and not just those
>>> methods that are defined inside an object literal. Then, a method would have
>>> to know what object it resides in, e.g. via an implicit parameter.
>>>
>>> We wish to avoid another parameter computed potentially differently for each
>>> call. It will cost
>>
>> What costs do you foresee?  I am not sure that there is much to
>> compute.  Assume a method call O.m().  Assume "m" is found on an
>> object P within O's protoype chain.  This will result in P.m being
>> called, for which the "super binding" can simply be computed as
>> P.[[Prototype]].  Next assume a direct function call, e.g.
>> f.call(this) or f() (this === undefined), the "super binding" here
>> could just be calculated as this.[[Prototype]] or undefined if |this|
>> is not an object.
>
> The call site (O.m()) does not statically know whether or not the the actual 
> function that will be called uses 'super'. Also,  only the call site knows 
> (dynamically) whether 'this' 'and 'super'  are different.  So, every method 
> call site  must always be prepared for the possibility that it is will be 
> invoking a function that uses 'super' and that the resolved 'this' and 
> 'super' values may be different. There are two alternatively ways that a ES 
> engine might deal with that possibility.  One way is for every call site to 
> always pass a separate 'super' value  as an additional implicit argument and 
> for every function to  accept to have a corresponding implicitly formal 
> parameter. If the property lookup found an own property the values passed for 
> 'this'' and 'super' would be the same but still must be passed as distinct 
> values.  The other way, is for each function to have an internal property 
> that says whether or not the function uses 'super'.  A call site, after 
> looking up a method property could test this bit of the resolved function and 
> only pass the implicit  'super' value to functions that actually use it. 
> However, conditionally passing 'super' based upon whether or not the callee 
> needs it probably has a higher execution cost than simply always passing a 
> distinct 'super' value. So, implementations are likely to use the always pass 
> super approach.
>
> So, at the very least "dynamic super" adds an extra implicit argument to 
> every call site. This is likely to have a real performance impact because the 
> dynamic average number of  function arguments is likely < 2 (assuming JS is 
> similar to other languages and counting the implicit 'this' argument).  
> Adding an additional implicit parameter to every call would hence be near a 
> 50% increase in argument passing overhead, on average.

I disagree that a dynamic super would lead to a '50% increase in
argument passing overhead, on average'.  First, there is the implicit
'arguments' argument, which is an object that actually needs to be
created per call site, not just a binding, and thus is presumably much
more expensive.  Second, 'argument passing overhead' involves sunk
costs that are not dependent on the number of argument bindings that
need to be created.  Third, implicit arguments, as 'super' would be,
should be less costly than explicit arguments since the argument value
does not need to be resolved.

A better estimate of the overhead of dynamic super would probably be
the overhead of an implicit 'this' binding, i.e. the cost of creating
a 'this' binding for a function activation that not involving an
explicit 'this' via Function.prototype.call or
Function.prototype.apply, or Function.prototype.bind.  Does anyone
have any estimates of this cost, either absolute or relative to some
other cost?

>
>
>
>>
>>> , and it will lead to surprises.
>>
>> What surprises do you foresee?  I think a static |super| in light of
>> ES's dynamic |this| would actually be much more surprising.  This
>> would lead to looking for properties in a static |super| object that
>> may be completely unrelated to the dynamic |this| value of a given
>> function activation, which would certainly be surprising.
>
> The meaning of 'super'  must be learned.  It isn't a very intuitive concept.  
> The 'static super' approach is essentially the same as is used in the most 
> widely used static and dynamic object-oriented languages.

The 'static super' approach is easier to understand, my argument is
that the 'dynamic super' approach is easier to actually *use*, at
least within ES.

>
> If we add a Object.defineMethod function that updates the super binding I 
> think we will eliminate most of the other possible sources of confusion.

That's not very convenient though compared to simple assignment, and I
don't think it composes with Object.defineProperty, meaning you cannot
have cont

Re: this vs thi\u0073

2011-06-21 Thread Allen Wirfs-Brock
ES5.1:
7.6.1   Reserved Words

A reserved word is an IdentifierName that cannot be used as an Identifier.

7.6Identifier Names and Identifiers

Identifier Names are tokens that are interpreted according to the grammar given 
in the “Identifiers” section of chapter 5 of the Unicode standard, with some 
small modifications. An Identifier is an IdentifierName that is not a 
ReservedWord (see 7.6.1). The Unicode identifier grammar is based on both 
normative and informative character categories specified by the Unicode 
Standard. The characters in the specified categories in version 3.0 of the 
Unicode standard must be treated as in those categories by all conforming 
ECMAScript implementations.

This standard specifies specific character additions: The dollar sign ($) and 
the underscore (_) are permitted anywhere in an IdentifierName.

Unicode escape sequences are also permitted in an IdentifierName, where they 
contribute a single character to the IdentifierName, as computed by the CV of 
the UnicodeEscapeSequence (see 7.8.4). The \ preceding the 
UnicodeEscapeSequence does not contribute a character to the IdentifierName. A 
UnicodeEscapeSequence cannot be used to put a character into an IdentifierName 
that would otherwise be illegal. In other words, if a \ UnicodeEscapeSequence 
sequence were replaced by its UnicodeEscapeSequence's CV, the result must still 
be a valid IdentifierName that has the exact same sequence of characters as the 
original IdentifierName. All interpretations of identifiers within this 
specification are based upon their actual characters regardless of whether or 
not an escape sequence was used to contribute any particular characters.


The red text would seems to say that \u0069f and if are the same reserved word.

This may not match implementations but it is what the spec. says.

ES3 didn't distinguish IdentifierName from Identifier but from a quick scan of 
the ES3 language I don't see that the spec. is any different in this regard.

Also, given the pervasive  substitution of Unicode escape sequences I don't see 
why they shouldn't be legal in reserved words.

Allen




On Jun 21, 2011, at 5:58 PM, Mike Samuel wrote:

> 2011/6/20 Luke Hoban :
>> My read of the spec is that thi\u0073 is a ReservedWord and should not be 
>> allowed as an Identifer.  So the following part of the examples quoted below 
>> should be an early error:
>> 
>>  var thi\u0073 = 42;
>> 
>> The text in 7.6 seems to address this with:
>> 
>> "All interpretations of identifiers within this specification are based upon 
>> their actual characters regardless of whether or not an escape sequence was 
>> used to contribute any particular characters."
> 
> I don't think this means what you think it means.
> 
> I think this means that the identifier foo is the same identifier as f\u006fo.
> 
> But in
> 
> if (false)
> alert(1)
> 
> "if" is not an identifier, whereas in
> 
> \u0069f(false)
> alert(1)
> 
> \u0069f is an identifier which would be the same as the identifier
> "if" if "if" could appear as an identifier unescaped.
> 
> Since "this" is not an identifier but appears explicitly in the text,
> that led me to assume that "thi\u0073" should behave differently from
> "this".
> 
> Every browser I have tested treats the identifier "i\u0066" distinctly
> from the keyword "if".
> Every browser I have tested treats the identifier "thi\u0073"
> distinctly from the keyword "this" in at least some cases, but only FF
> passes all the tests I've come up with.
> ___
> 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: Making "super" work outside a literal?

2011-06-21 Thread Peter Michaux
On Tue, Jun 21, 2011 at 1:55 AM, Mariusz Nowak
 wrote:
> Peter Michaux wrote:

>> You want to allow the API (a.k.a. public methods) of an object to be
>> overridden, but you don't want the functionality of any non-overidden
>> API methods to change. In short, you want to avoid the template
>> pattern. I gave a synthetic example in the sideways calls thread I
>> started.

> I'm actually not sure about that. I would even say that allowing such
> sideway calls within 'instance' methods would be bad hint. I wouldn't like
> to approach following code, it doesn't allow to extend A the way I may need
> to:
>
> var A = function () {};
> A.prototype = {
>        one: function () {
>                return A.prototype.two.call(this, args...);
>        },
>        two: function () {
>                ...
>        }
> };

Yes it may seem inconvenient but it is a decision for the the person
creating the class, not the person trying to extend the class.

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


Re: this vs thi\u0073

2011-06-21 Thread Mike Samuel
2011/6/20 Luke Hoban :
> My read of the spec is that thi\u0073 is a ReservedWord and should not be 
> allowed as an Identifer.  So the following part of the examples quoted below 
> should be an early error:
>
>  var thi\u0073 = 42;
>
> The text in 7.6 seems to address this with:
>
> "All interpretations of identifiers within this specification are based upon 
> their actual characters regardless of whether or not an escape sequence was 
> used to contribute any particular characters."

I don't think this means what you think it means.

I think this means that the identifier foo is the same identifier as f\u006fo.

But in

if (false)
alert(1)

"if" is not an identifier, whereas in

\u0069f(false)
alert(1)

\u0069f is an identifier which would be the same as the identifier
"if" if "if" could appear as an identifier unescaped.

Since "this" is not an identifier but appears explicitly in the text,
that led me to assume that "thi\u0073" should behave differently from
"this".

Every browser I have tested treats the identifier "i\u0066" distinctly
from the keyword "if".
Every browser I have tested treats the identifier "thi\u0073"
distinctly from the keyword "this" in at least some cases, but only FF
passes all the tests I've come up with.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


imperative vs functional APIs or: how to work with constant objects?

2011-06-21 Thread Claus Reinke
Javascript data structure operations: some of the APIs are imperative, 
some are functional, some are mixed. Having functional equivalents
to all imperative data structure operations is necessary to support 
expression-oriented programming over constant data structures.


"imperative" here refers to operations that are designed to be used 
as statements, changing inputs by side-effect, while "functional" 
refers to operations designed to be used as expressions, leaving 
their inputs unchanged. A familiar example is the Array API, e.g.:


   array.concat([1])- returns a modified copy of array, expression

   array.push(1)- modifies array in place, "statement"

It does seem as if older API elements tend to be imperative while 
newer ones tend to be functional. However, not all imperative

operations have functional counterparts yet, and with increasing
focus on constant and frozen objects, the need for functional
operations is going to increase.

In particular, I have been wondering about how freezing objects
curtails what I am able to do with them. Having worked with pure
functional language for a long time, I really like the advantages of
frozen/constant objects, both for avoiding bugs and to enable
optimizations, but I'm not used to not having a full set of 
operations to work with such objects:


Example 1: constant functions, prototypes and toString

   The standard API for functions requires imperative operations
   for both prototypical inheritance and for string representation.

   const C() {}
   // C.prototype.toString = function() { return 'C()' }
   // C.toString = function() { return 'C()' }

Example 2: property update

   The standard API for object property update is imperative.

   const obj = Object.freeze({ age : 1, .. });
   const older_obj = // a modified copy of obj, with age : 2??

The standard APIs for these fundamental operations are imperative
and so are not available on frozen objects (this also applies to the
record strawman, for instance).

How does one achieve the effects of these operations on frozen
objects, by creating modified copies? For an expression-oriented 
style of programming where no object is ever modified in place, 
it seems one has to use a lower level API, perhaps by calling

Object.create and Object.freeze to implement some form of
Object.clone, then mixing in the update on the clone before 
freezing it. Or perhaps using proxies to achieve the effect..


The situation is somewhat similar to the declarative object 
initializers being worked on as object literal extensions, but 
those don't seem to help here.


What is the best way of doing functional/declarative/expression-
oriented object modification in ES5 or ES/next? Is there really an 
imperative-preferred flaw in the current design?


Claus


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


Re: Making "super" work outside a literal?

2011-06-21 Thread Allen Wirfs-Brock

On Jun 21, 2011, at 4:13 PM, Sean Eagan wrote:

> On Tue, Jun 21, 2011 at 9:40 AM, Axel Rauschmayer  wrote:
 We wish to avoid another parameter computed potentially differently for 
 each
 call. It will cost
>>> 
>>> What costs do you foresee?  I am not sure that there is much to
>>> compute.  Assume a method call O.m().  Assume "m" is found on an
>>> object P within O's protoype chain.  This will result in P.m being
>>> called, for which the "super binding" can simply be computed as
>>> P.[[Prototype]].  Next assume a direct function call, e.g.
>>> f.call(this) or f() (this === undefined), the "super binding" here
>>> could just be calculated as this.[[Prototype]] or undefined if |this|
>>> is not an object.
>> 
>> 
>> This may already be what you are suggesting, so to clarify:
>> 
>> I would introduce a binding called "here" that points to the object P where 
>> m has been found.
>> 
>> - Method that uses super: compute super as here.[[Prototype]]
>> - Non-method function that uses super: "here" is undefined, using super 
>> causes an error.
>> 
>> If super is not used there is little computational cost! (Other than a 
>> binding per function call which may still be prohibitive.)
> 
> Regardless of any "here" binding, "super" would only need to be bound
> within functions that actually use it (the same should be true for
> |this|).  However, as I mentioned, it seems the cost of a dynamic
> |super| binding should be relatively low, comparable to the cost of a
> dynamic |this| binding.
> 

No, dynamic 'super' is an additional overhead  that is the same as the dynamic 
'this' overhead.  Dynamic 'super' essentially doubles the dynamic 'this' 
overhead on every call.

Allen

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


Re: Making "super" work outside a literal?

2011-06-21 Thread Allen Wirfs-Brock

On Jun 21, 2011, at 3:28 PM, Sean Eagan wrote:

> On Sun, Jun 19, 2011 at 2:14 PM, Brendan Eich  wrote:
>> On Jun 19, 2011, at 10:20 AM, Axel Rauschmayer wrote:
>> 
>> It would be nice if "super" could work in any method and not just those
>> methods that are defined inside an object literal. Then, a method would have
>> to know what object it resides in, e.g. via an implicit parameter.
>> 
>> We wish to avoid another parameter computed potentially differently for each
>> call. It will cost
> 
> What costs do you foresee?  I am not sure that there is much to
> compute.  Assume a method call O.m().  Assume "m" is found on an
> object P within O's protoype chain.  This will result in P.m being
> called, for which the "super binding" can simply be computed as
> P.[[Prototype]].  Next assume a direct function call, e.g.
> f.call(this) or f() (this === undefined), the "super binding" here
> could just be calculated as this.[[Prototype]] or undefined if |this|
> is not an object.

The call site (O.m()) does not statically know whether or not the the actual 
function that will be called uses 'super'. Also,  only the call site knows 
(dynamically) whether 'this' 'and 'super'  are different.  So, every method 
call site  must always be prepared for the possibility that it is will be 
invoking a function that uses 'super' and that the resolved 'this' and 'super' 
values may be different. There are two alternatively ways that a ES engine 
might deal with that possibility.  One way is for every call site to always 
pass a separate 'super' value  as an additional implicit argument and for every 
function to  accept to have a corresponding implicitly formal parameter. If the 
property lookup found an own property the values passed for 'this'' and 'super' 
would be the same but still must be passed as distinct values.  The other way, 
is for each function to have an internal property that says whether or not the 
function uses 'super'.  A call site, after looking up a meth
 od property could test this bit of the resolved function and only pass the 
implicit  'super' value to functions that actually use it. However, 
conditionally passing 'super' based upon whether or not the callee needs it 
probably has a higher execution cost than simply always passing a distinct 
'super' value. So, implementations are likely to use the always pass super 
approach. 

So, at the very least "dynamic super" adds an extra implicit argument to every 
call site. This is likely to have a real performance impact because the dynamic 
average number of  function arguments is likely < 2 (assuming JS is similar to 
other languages and counting the implicit 'this' argument).  Adding an 
additional implicit parameter to every call would hence be near a 50% increase 
in argument passing overhead, on average.



> 
>> , and it will lead to surprises.
> 
> What surprises do you foresee?  I think a static |super| in light of
> ES's dynamic |this| would actually be much more surprising.  This
> would lead to looking for properties in a static |super| object that
> may be completely unrelated to the dynamic |this| value of a given
> function activation, which would certainly be surprising.

The meaning of 'super'  must be learned.  It isn't a very intuitive concept.  
The 'static super' approach is essentially the same as is used in the most 
widely used static and dynamic object-oriented languages.

If we add a Object.defineMethod function that updates the super binding I think 
we will eliminate most of the other possible sources of confusion. 

> 
>> Also, anything reachable from |this| can be computed using ES5's Object.*
>> APIs.
> 
> Wouldn't the ES5 Object.* APIs be unreliable and inconvenient for such
> a calculation?  It is impossible to determine which property name a
> method m was accessed with from within m, and even if you assume a
> static property name p, climbing the prototype chain of |this| to
> determine on which object m was found via
> |Object.getOwnPropertyDescriptor(prototypeChainObject, p)| may not be
> accurate if there are any proxies in the prototype chain, or if
> anything has changed in the prototype chain since it was initially
> climbed by the engine.

All true, but what is the use case for actually doing this.  'super' is 
intended to address the most common static use cases. 

I suspect that the pervasive overhead of dynamic super is what has kept it out 
of the language up to now. I really don't think that implementations are going 
to look favorably upon it now.




> 
>> Quoting from
>> http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super :
>> 
>>  When a function contains a reference to super, that function internally
>> captures an internal reference to the [[Prototype]] of the object created by
>> the enclosing object initialiser. If such a function is subsequently
>> extracted from the original object and installed as a property value in some
>> other object, the internal reference to the origin

Analog to Object.getPropertyDescriptor() for *changing* a property value?

2011-06-21 Thread Axel Rauschmayer
As a loose analog to the prototype-chain-traversing getPropertyDescriptor(), I 
would still like to have something that allows one to easily *change* 
properties higher up the prototype chain (e.g. to use a prototype to share 
state).

Maybe it would be enough to just have Object.getDefiningObject(obj, propName):
http://www.mail-archive.com/es-discuss@mozilla.org/msg06652.html

But I can also imagine syntactic sugar:
obj.foo := "abc"
desugars to
Object.getDefiningObject(obj, "foo").foo = "abc"

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: Making "super" work outside a literal?

2011-06-21 Thread Sean Eagan
On Tue, Jun 21, 2011 at 9:40 AM, Axel Rauschmayer  wrote:
>>> We wish to avoid another parameter computed potentially differently for each
>>> call. It will cost
>>
>> What costs do you foresee?  I am not sure that there is much to
>> compute.  Assume a method call O.m().  Assume "m" is found on an
>> object P within O's protoype chain.  This will result in P.m being
>> called, for which the "super binding" can simply be computed as
>> P.[[Prototype]].  Next assume a direct function call, e.g.
>> f.call(this) or f() (this === undefined), the "super binding" here
>> could just be calculated as this.[[Prototype]] or undefined if |this|
>> is not an object.
>
>
> This may already be what you are suggesting, so to clarify:
>
> I would introduce a binding called "here" that points to the object P where m 
> has been found.
>
> - Method that uses super: compute super as here.[[Prototype]]
> - Non-method function that uses super: "here" is undefined, using super 
> causes an error.
>
> If super is not used there is little computational cost! (Other than a 
> binding per function call which may still be prohibitive.)

Regardless of any "here" binding, "super" would only need to be bound
within functions that actually use it (the same should be true for
|this|).  However, as I mentioned, it seems the cost of a dynamic
|super| binding should be relatively low, comparable to the cost of a
dynamic |this| binding.

>
> --
> Dr. Axel Rauschmayer
>
> a...@rauschma.de
> twitter.com/rauschma
>
> home: rauschma.de
> blog: 2ality.com
>
>
>
>



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


Re: Making "super" work outside a literal?

2011-06-21 Thread Axel Rauschmayer
>> We wish to avoid another parameter computed potentially differently for each
>> call. It will cost
> 
> What costs do you foresee?  I am not sure that there is much to
> compute.  Assume a method call O.m().  Assume "m" is found on an
> object P within O's protoype chain.  This will result in P.m being
> called, for which the "super binding" can simply be computed as
> P.[[Prototype]].  Next assume a direct function call, e.g.
> f.call(this) or f() (this === undefined), the "super binding" here
> could just be calculated as this.[[Prototype]] or undefined if |this|
> is not an object.


This may already be what you are suggesting, so to clarify:

I would introduce a binding called "here" that points to the object P where m 
has been found.

- Method that uses super: compute super as here.[[Prototype]]
- Non-method function that uses super: "here" is undefined, using super causes 
an error.

If super is not used there is little computational cost! (Other than a binding 
per function call which may still be prohibitive.)

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: Making "super" work outside a literal?

2011-06-21 Thread Sean Eagan
On Sun, Jun 19, 2011 at 2:14 PM, Brendan Eich  wrote:
> On Jun 19, 2011, at 10:20 AM, Axel Rauschmayer wrote:
>
> It would be nice if "super" could work in any method and not just those
> methods that are defined inside an object literal. Then, a method would have
> to know what object it resides in, e.g. via an implicit parameter.
>
> We wish to avoid another parameter computed potentially differently for each
> call. It will cost

What costs do you foresee?  I am not sure that there is much to
compute.  Assume a method call O.m().  Assume "m" is found on an
object P within O's protoype chain.  This will result in P.m being
called, for which the "super binding" can simply be computed as
P.[[Prototype]].  Next assume a direct function call, e.g.
f.call(this) or f() (this === undefined), the "super binding" here
could just be calculated as this.[[Prototype]] or undefined if |this|
is not an object.

> , and it will lead to surprises.

What surprises do you foresee?  I think a static |super| in light of
ES's dynamic |this| would actually be much more surprising.  This
would lead to looking for properties in a static |super| object that
may be completely unrelated to the dynamic |this| value of a given
function activation, which would certainly be surprising.

> Also, anything reachable from |this| can be computed using ES5's Object.*
> APIs.

Wouldn't the ES5 Object.* APIs be unreliable and inconvenient for such
a calculation?  It is impossible to determine which property name a
method m was accessed with from within m, and even if you assume a
static property name p, climbing the prototype chain of |this| to
determine on which object m was found via
|Object.getOwnPropertyDescriptor(prototypeChainObject, p)| may not be
accurate if there are any proxies in the prototype chain, or if
anything has changed in the prototype chain since it was initially
climbed by the engine.

> Quoting from
> http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super :
>
>  When a function contains a reference to super, that function internally
> captures an internal reference to the [[Prototype]] of the object created by
> the enclosing object initialiser. If such a function is subsequently
> extracted from the original object and installed as a property value in some
> other object, the internal reference to the original [[Prototype]] is not
> modified. Essentially, when a function references super it is statically
> referencing a specific object that is identified when the function is
> defined and not the [[Prototype]] of the object from which the function was
> most recently retrieved.
>
> This behavior is consistent with that of most other languages that provide
> reflection function to extract methods containing super and then
> independently invoke them.

Consistency with other languages is valuable, but consistency with
this language (ES) is vital.  A static |super| would be inconsistent
with ES's dynamic |this|.  The semantics of |super| will be related to
the value of |this| no matter how |super| ends up being specified, and
thus the "super binding" should be calculated in terms of the "this
binding" if intra-language consistency is to be kept.

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



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


[Harmony proxies] thought on the "traps that return arrays of property names" open issue

2011-06-21 Thread David Bruant

Hi,

I've recently seen the slides of Dave Mandelin "Know your engine - How 
to make your JavaScript fast" [1]. If I understand slide 121 correctly, 
then a type inference engine can know in some cases if all elements of a 
(dense?) array have the same type.


On the Harmony proxies proposal, one open issue is the following:
"Traps that return arrays of property names, such as 
getOwnPropertyNames: should all values in the returned array be coerced 
to String before being returned to the user? (...)"
Regardless of how the problem is seen, considering such a things would 
require to look at the type of each element and convert it if it's not a 
string.
Assuming that programmers already generate arrays of strings (the 
strength of this assumption would need investigation) and assuming that 
the engine is able to realize it in most cases (needs to be investigated 
as well), then the cost of verifying the invariant is cheap.
My point is that in good cases, enforcing the invariant "has to return 
an array of strings" in good cases may be cheap (at least cheaper than 
with a naive approach).


Of course, the assumed cheapness of the invariant enforcement in good 
cases depends on having a type inference engine able to do such checks. 
If I understand well, Mozilla has one able to do that (tell me if I'm 
wrong) and it's open source. Other may have different opinions, but I 
think that if there was another different open source type inference 
engine with the same capacity, then having such an engine could be 
considered as "not that hard", because anyone who would like to create 
one could at least see 2 different approaches and implementations.


David

[1] http://www.slideshare.net/newmovie/know-yourengines-velocity2011
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Making "super" work outside a literal?

2011-06-21 Thread Axel Rauschmayer
> From: Mariusz Nowak 
> Date: June 21, 2011 10:54:29 GMT+02:00
> 
>> 
> From my perspective, this proposal looks perfect. I wouldn't look further :)


I agree. Object literal extensions are all very nice.

Note that (as Brendan mentioned) |here| (which I used to explain things) would 
be a static value, not a dynamic one (unlike |this|). Or (a static) |super| 
might just be used directly.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: A shorthand for Object.defineProperty?

2011-06-21 Thread Axel Rauschmayer
 Do we really need the dynamic this arrow ->, or can we make do with just 
 the lexical this arrow =>.
>> Are functions that depend on dynamic |this| ever *not* methods?
> 
> Sure. The main use-case is constructors (and you can make a function do 
> double-duty, as a constructor or a function called without 'new').

With classes, constructors will become methods, right?

> Also, some times, people write functions not used as methods but called via 
> .call or .apply. It happens.

Wouldn’t it be better to have lexical |this| in these cases, so that 
foo.call(null, ...) does not affect |this|? But I see what you mean, you cannot 
use normal .bind(), because of the way it handles the arguments that the bound 
function receives. Maybe use something like the following to implement =>, then?

Function.prototype.bindOnlyThis = function (myThis) {
var that = this;
return function() {
return that.apply(myThis, arguments);
};
}

>> Wouldn’t you always want to use an object literal for methods, especially if 
>> some features (such as |super|) depend on it?
> 
> Probably. But so what?
> 
> We're not making mandatory syntax either way with function, so why should we 
> with arrow?

Old-style functions would be rarely used and there would be a clear separation 
of concerns:
- Want a method? Use an object literal.
- Want a function that is not a method (i.e., lexical this)? Use an arrow 
function with =>

This would make things easier to understand. When I explain this aspect of 
JavaScript to others, they are often stumped, but I have never encountered 
anyone who was confused by Python:
class MyClass:
def mymethod(self):
return "hello world"
def myfunction():
return "hello world"

So this is probably my real point: can we make things as un-confusing as in 
Python?

>> Maybe I just like the distinction introduced by block lambdas too much:
>> - dynamic this --> existing functions and methods
>> - lexical this --> new, more compact construct, mainly used as the argument 
>> of functions and methods.
> 
> Block-lambdas are not arrows. Arrows are just syntax and try to shorten 
> function usage in general (including the .bind or var self=this; idiom). 
> Block-lambdas must preserve Tennent's Correspondence Principle, so they have 
> no choice but to treat |this| lexically.

I know. But block-lambdas enforce a separation of concerns (because they have 
no choice, really) that I would like short-syntax functions (arrows or not) to 
enforce, as well.

>> This distinction works well as a rule of thumb and keeps things easy to 
>> explain.
> 
> It's not that simple: existing functions can and do use various binding hacks 
> to make |this| or a substitute "lexical". Anyway, functions have |this| 
> parameters, whether created by old function or new arrow syntax.

Right. That could be a problem, the abstraction I have in mind might become 
leaky at some point.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: this vs thi\u0073

2011-06-21 Thread Geoffrey Sneddon

On 21/06/11 00:50, Luke Hoban wrote:

My read of the spec is that thi\u0073 is a ReservedWord and should not be 
allowed as an Identifer.  So the following part of the examples quoted below 
should be an early error:

   var thi\u0073 = 42;

The text in 7.6 seems to address this with:

"All interpretations of identifiers within this specification are based upon their 
actual characters regardless of whether or not an escape sequence was used to contribute 
any particular characters."


There's also  
which states (after saying "this is very rough"):


"Identifiers containing escape sequences are not equivalent to fully 
unescaped identifiers in the case that, after fully unescaping 
identifier, it is a ReservedWord. In particular it is possible to create 
Identifiers that unescape to a reserved word so long as at least one 
character is fully escaped. Subsequent use of such identifiers must also 
have at least one character escaped (otherwise the reserved word will be 
used instead) but it need not be the same character(s) as that 
originally used to create the identifier."


--
Geoffrey Sneddon — Opera Software


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


Re: Making "super" work outside a literal?

2011-06-21 Thread Mariusz Nowak



Peter Michaux wrote:
> 
> On Mon, Jun 20, 2011 at 3:23 PM, Axel Rauschmayer 
> wrote:
> 
>> What is the use case for sideways calls? Can you point me to an example?
> 
> You want to allow the API (a.k.a. public methods) of an object to be
> overridden, but you don't want the functionality of any non-overidden
> API methods to change. In short, you want to avoid the template
> pattern. I gave a synthetic example in the sideways calls thread I
> started.
> 

Peter,

I'm actually not sure about that. I would even say that allowing such
sideway calls within 'instance' methods would be bad hint. I wouldn't like
to approach following code, it doesn't allow to extend A the way I may need
to:

var A = function () {};
A.prototype = {
one: function () {
return A.prototype.two.call(this, args...);
},
two: function () {
...
}
};

If we definitely need to call A.prototype.two whether we extended A or not,
then we probably talk about 'static' method which should not be called on
instance and should be defined directly on A (or privately within closure),
then we may just call it A.two(args...). At least that's what my OOP
experience says.

I understand your example at
http://old.nabble.com/super%2C-self%2C-and-sideways---durable-vs.-template-p31830714.html
to me it's just programmer mistake that should throw error.
Maybe you're looking for some pattern that can be realized using 'static'
methods (?) but forcing or introducing such behavior somewhere close 'this'
or 'super' logic might not be what people expect. My experience is not that
vast, is there any language that provide sugar for such calls ?


-
Mariusz Nowak

https://github.com/medikoo
-- 
View this message in context: 
http://old.nabble.com/Re%3A-es-discuss-Digest%2C-Vol-52%2C-Issue-117-tp31889060p31892412.html
Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at 
Nabble.com.

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


Re: es-discuss Digest, Vol 52, Issue 117

2011-06-21 Thread Mariusz Nowak



rauschma wrote:
> 
> 
>> var c1 = Object.create(C);
>> obj.one(); // 'A.foo'
> 
> That would be c1.one(), right?
> 

Yes, sorry edited post twice.


rauschma wrote:
> 
> 
> |here| === C and thus the search for super.one starts in B and finds
> A.one.
> 
>> B.two = function () {
>>  this.three();
>> };
>> B.three =  function () {
>>  return 'B.three';
>> };
>> C.two = function () {
>>  super.two();
>> };
>> C.three = function () {
>>  return 'C.three';
>> };
>> 
>> var c2 = Object.create(C);
>> c2.two();  // C.three
> 
> |here| === C and thus super.two === B.two
> 
> B.two() uses the original and unchanged |this| which is still c2.
> => this.three === C.three
> 
> SUMMARY: I agree with your findings.
> 

>From my perspective, this proposal looks perfect. I wouldn't look further :)

-
Mariusz Nowak

https://github.com/medikoo
-- 
View this message in context: 
http://old.nabble.com/Re%3A-es-discuss-Digest%2C-Vol-52%2C-Issue-117-tp31889060p31892405.html
Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at 
Nabble.com.

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


Re: this vs thi\u0073

2011-06-21 Thread Allen Wirfs-Brock

On Jun 21, 2011, at 12:50 AM, Luke Hoban wrote:

> My read of the spec is that thi\u0073 is a ReservedWord and should not be 
> allowed as an Identifer.  So the following part of the examples quoted below 
> should be an early error:
> 
>  var thi\u0073 = 42;
> 
> The text in 7.6 seems to address this with:
> 
> "All interpretations of identifiers within this specification are based upon 
> their actual characters regardless of whether or not an escape sequence was 
> used to contribute any particular characters."
> 
> Luke

+1

I can't dig into the spec. right now but the section Luke quoted  is the one I 
was going to try to dig for.

Allen









> 
> -Original Message-
> From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] 
> On Behalf Of Mike Samuel
> Sent: Monday, June 20, 2011 2:18 PM
> To: Oliver Hunt
> Cc: es-discuss
> Subject: Re: this vs thi\u0073
> 
> 2011/6/20 Oliver Hunt :
>> Without looking at the spec but just based on what I know our lexer (JSC) 
>> does, we won't consider any identifier with escaped characters to be a 
>> keyword, so yes you could make identifiers that technically match language 
>> keywords, but you'd never be able to use them directly (without escaping).
> 
> You can due to global object aliasing.
> 
>  var thi\u0073 = 42;
>  alert([this.this === 42,  // Look ma, no escaping!
>  this["this"] === 42]);  // Look ma, still no escaping!
> 
> works in Firefox.
> 
> The first is legal because MemberExpression is defined as
> MemberExpression . IdentifierName
> not
> MemberExpression . Identifier
> and it is only Identifier that is not allowed to be a reserved word
> Identifier :: IdentifierName but not ReservedWord
> IdentifierName :: IdentifierStart
>  | IdentifierName IdentifierPart 
> ___
> 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


Re: non-ES5 strict mode restrictions

2011-06-21 Thread Allen Wirfs-Brock

On Jun 20, 2011, at 7:40 PM, Brendan Eich wrote:

> On Jun 20, 2011, at 11:17 AM, Mark S. Miller wrote:
> 
>> Wow, good catch. That's an oversight -- I don't remember this case being 
>> noticed when we discussed this issue. I agree with your conclusion on three 
>> grounds:
> 
> I remember this, or at least, I remember discussions about it. It's no 
> different from var in strict eval, AFAICT. I think the spec has enough 
> information to reach the conclusion that no exception should be thrown.

+1

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