Re: Type of property names, as seen by proxy traps

2011-07-14 Thread Tom Van Cutsem
Follow-up: I updated 
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics with a
more precise specification of the default behavior of all derived traps.
This should also resolve the double-coercion issue with Object.keys.

In summary:
- for has, hasOwn and get it's easy to fall back on specifications of
existing built-ins (Object.[[HasProperty]] for has,
Object.prototype.hasOwnProperty for hasOwn and Object.[[Get]] for get)

- for set, falling back on Object.[[Put]] is not ideal, as this built-in
performs redundant invocations of [[Get{Own}Property]] through [[CanPut]].
Starting from Object.[[Put]] and the default set trap as specified in JS
itself, I formulated a new DefaultPut algorithm that avoids this
redundancy.

- for keys and enumerate, there is no proper built-in to fall back on. I
added two algorithms (FilterEnumerableOwn and FilterEnumerable) that take
the uncoerced result of the get{Own}PropertyNames trap, and filter out the
enumerable properties, specced after Array.prototype.filter.

I also updated 
http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults so
that it is clear that that section is only a non-normative description of
how derived traps could be implemented in pure Javascript.

Cheers,
Tom

2011/7/8 Tom Van Cutsem tomvc...@gmail.com

 I believe the alternative that David is talking about is the following
 (pending the acceptance of 
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)

 keys: function(proxy) {
   return Object.getOwnPropertyNames(proxy).filter(
   function (name) { return Object.getOwnPropertyDescriptor(proxy,
 name).enumerable });
 }

 (assuming that Object here refers to the built-in Object)

 With this definition, I don't see the need for double coercion: the
 handler's getOwnPropertyNames trap is called, and its result is coerced.
 Then, the proxy implementation knows that each of the above |name|s passed
 to getOwnPropertyDescriptor will be a String already, so it doesn't need
 to coerce again. Finally, `keys' does not need to coerce its own result
 array, since it is simply a filtered version of an already fresh, coerced
 array.

 Perhaps all self-sends to fundamental traps should be expressed in terms of
 the operation that causes the trap, rather than a direct trap invocation.
 Similar issues could arise in the default 'set' trap behavior when it calls
 'this.defineProperty' rather than 'Object.defineProperty(proxy,...)'.

 2011/7/7 Andreas Rossberg rossb...@google.com

 On 7 July 2011 19:35, David Bruant david.bru...@labri.fr wrote:
  No, with the current keys default trap (calling
  this.getOwnPropertyNames()) there is no double conversion. Only one at
  the exit of the keys trap. There would be 2 conversions if the keys
  trap had the proxy argument (based on
 
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
  and if internally, the default keys trap was calling
  Object.getOwnPropertyNames(proxy) (which would call the trap and do
  type coercion).
 
  But the current implementation and a type coercion only when going out
  of traps would do double-conversion.
  not. would not do double-conversion, sorry.

 I thought the fix we were discussing was changing the `keys' default trap
 from

 keys: function() {
  return this.getOwnPropertyNames().filter(
function (name) { return
 this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
 }

 to something along the lines of

 keys: function() {
  return this.getOwnPropertyNames().filter(
function (name) { return this.getOwnPropertyDescriptor('' +
 name).enumerable }.bind(this));
 }

 That would fix passing non-strings to the getOwnPropertyDescriptor
 trap, but introduce double conversions when you invoke Object.keys.
 I'm not sure what alternative you are proposing now.

 /Andreas
 ___
 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: Type of property names, as seen by proxy traps

2011-07-14 Thread Andreas Rossberg
Very much appreciated. Given all the nasty mutability in JS, I think
for the non-normative JS implementations you also might want to note
that it assumes that nobody has hampered with the primordial Object
object.

/Andreas


On 14 July 2011 12:34, Tom Van Cutsem tomvc...@gmail.com wrote:
 Follow-up: I updated
 http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics with a
 more precise specification of the default behavior of all derived traps.
 This should also resolve the double-coercion issue with Object.keys.
 In summary:
 - for has, hasOwn and get it's easy to fall back on specifications of
 existing built-ins (Object.[[HasProperty]] for has,
 Object.prototype.hasOwnProperty for hasOwn and Object.[[Get]] for get)
 - for set, falling back on Object.[[Put]] is not ideal, as this built-in
 performs redundant invocations of [[Get{Own}Property]] through [[CanPut]].
 Starting from Object.[[Put]] and the default set trap as specified in JS
 itself, I formulated a new DefaultPut algorithm that avoids this
 redundancy.
 - for keys and enumerate, there is no proper built-in to fall back on. I
 added two algorithms (FilterEnumerableOwn and FilterEnumerable) that take
 the uncoerced result of the get{Own}PropertyNames trap, and filter out the
 enumerable properties, specced after Array.prototype.filter.
 I also updated
 http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults so
 that it is clear that that section is only a non-normative description of
 how derived traps could be implemented in pure Javascript.
 Cheers,
 Tom

 2011/7/8 Tom Van Cutsem tomvc...@gmail.com

 I believe the alternative that David is talking about is the following
 (pending the acceptance of
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
 keys: function(proxy) {
   return Object.getOwnPropertyNames(proxy).filter(
       function (name) { return Object.getOwnPropertyDescriptor(proxy,
 name).enumerable });
 }
 (assuming that Object here refers to the built-in Object)
 With this definition, I don't see the need for double coercion: the
 handler's getOwnPropertyNames trap is called, and its result is coerced.
 Then, the proxy implementation knows that each of the above |name|s passed
 to getOwnPropertyDescriptor will be a String already, so it doesn't need
 to coerce again. Finally, `keys' does not need to coerce its own result
 array, since it is simply a filtered version of an already fresh, coerced
 array.
 Perhaps all self-sends to fundamental traps should be expressed in terms
 of the operation that causes the trap, rather than a direct trap invocation.
 Similar issues could arise in the default 'set' trap behavior when it calls
 'this.defineProperty' rather than 'Object.defineProperty(proxy,...)'.
 2011/7/7 Andreas Rossberg rossb...@google.com

 On 7 July 2011 19:35, David Bruant david.bru...@labri.fr wrote:
  No, with the current keys default trap (calling
  this.getOwnPropertyNames()) there is no double conversion. Only one at
  the exit of the keys trap. There would be 2 conversions if the keys
  trap had the proxy argument (based on
 
  http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
  and if internally, the default keys trap was calling
  Object.getOwnPropertyNames(proxy) (which would call the trap and do
  type coercion).
 
  But the current implementation and a type coercion only when going out
  of traps would do double-conversion.
  not. would not do double-conversion, sorry.

 I thought the fix we were discussing was changing the `keys' default trap
 from

 keys: function() {
  return this.getOwnPropertyNames().filter(
    function (name) { return
 this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
 }

 to something along the lines of

 keys: function() {
  return this.getOwnPropertyNames().filter(
    function (name) { return this.getOwnPropertyDescriptor('' +
 name).enumerable }.bind(this));
 }

 That would fix passing non-strings to the getOwnPropertyDescriptor
 trap, but introduce double conversions when you invoke Object.keys.
 I'm not sure what alternative you are proposing now.

 /Andreas
 ___
 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: Type of property names, as seen by proxy traps

2011-07-14 Thread Andreas Rossberg
tampered, not hampered, of course...

On 14 July 2011 12:52, Andreas Rossberg rossb...@google.com wrote:
 Very much appreciated. Given all the nasty mutability in JS, I think
 for the non-normative JS implementations you also might want to note
 that it assumes that nobody has hampered with the primordial Object
 object.

 /Andreas


 On 14 July 2011 12:34, Tom Van Cutsem tomvc...@gmail.com wrote:
 Follow-up: I updated
 http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics with a
 more precise specification of the default behavior of all derived traps.
 This should also resolve the double-coercion issue with Object.keys.
 In summary:
 - for has, hasOwn and get it's easy to fall back on specifications of
 existing built-ins (Object.[[HasProperty]] for has,
 Object.prototype.hasOwnProperty for hasOwn and Object.[[Get]] for get)
 - for set, falling back on Object.[[Put]] is not ideal, as this built-in
 performs redundant invocations of [[Get{Own}Property]] through [[CanPut]].
 Starting from Object.[[Put]] and the default set trap as specified in JS
 itself, I formulated a new DefaultPut algorithm that avoids this
 redundancy.
 - for keys and enumerate, there is no proper built-in to fall back on. I
 added two algorithms (FilterEnumerableOwn and FilterEnumerable) that take
 the uncoerced result of the get{Own}PropertyNames trap, and filter out the
 enumerable properties, specced after Array.prototype.filter.
 I also updated
 http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults so
 that it is clear that that section is only a non-normative description of
 how derived traps could be implemented in pure Javascript.
 Cheers,
 Tom

 2011/7/8 Tom Van Cutsem tomvc...@gmail.com

 I believe the alternative that David is talking about is the following
 (pending the acceptance of
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
 keys: function(proxy) {
   return Object.getOwnPropertyNames(proxy).filter(
       function (name) { return Object.getOwnPropertyDescriptor(proxy,
 name).enumerable });
 }
 (assuming that Object here refers to the built-in Object)
 With this definition, I don't see the need for double coercion: the
 handler's getOwnPropertyNames trap is called, and its result is coerced.
 Then, the proxy implementation knows that each of the above |name|s passed
 to getOwnPropertyDescriptor will be a String already, so it doesn't need
 to coerce again. Finally, `keys' does not need to coerce its own result
 array, since it is simply a filtered version of an already fresh, coerced
 array.
 Perhaps all self-sends to fundamental traps should be expressed in terms
 of the operation that causes the trap, rather than a direct trap invocation.
 Similar issues could arise in the default 'set' trap behavior when it calls
 'this.defineProperty' rather than 'Object.defineProperty(proxy,...)'.
 2011/7/7 Andreas Rossberg rossb...@google.com

 On 7 July 2011 19:35, David Bruant david.bru...@labri.fr wrote:
  No, with the current keys default trap (calling
  this.getOwnPropertyNames()) there is no double conversion. Only one at
  the exit of the keys trap. There would be 2 conversions if the keys
  trap had the proxy argument (based on
 
  http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
  and if internally, the default keys trap was calling
  Object.getOwnPropertyNames(proxy) (which would call the trap and do
  type coercion).
 
  But the current implementation and a type coercion only when going out
  of traps would do double-conversion.
  not. would not do double-conversion, sorry.

 I thought the fix we were discussing was changing the `keys' default trap
 from

 keys: function() {
  return this.getOwnPropertyNames().filter(
    function (name) { return
 this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
 }

 to something along the lines of

 keys: function() {
  return this.getOwnPropertyNames().filter(
    function (name) { return this.getOwnPropertyDescriptor('' +
 name).enumerable }.bind(this));
 }

 That would fix passing non-strings to the getOwnPropertyDescriptor
 trap, but introduce double conversions when you invoke Object.keys.
 I'm not sure what alternative you are proposing now.

 /Andreas
 ___
 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: Type of property names, as seen by proxy traps

2011-07-08 Thread Tom Van Cutsem
2011/7/7 David Herman dher...@mozilla.com

 2011/7/6 Andreas Rossberg rossb...@google.com

 While putting together some test cases for Object.keys, I wondered: is
 it intended that property names are always passed to traps as strings?


 That is indeed the intent.


 Unless they are private name objects, right?


I'm not sure. I briefly checked the private names proposal 
http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects and I
think the detailed interaction with proxies still has to be fleshed out.

The proposal does mention: All reflective operations that produce a
property name, when reflecting on a private name, produce the name’s .public
property instead of the name itself.

Would the same hold for reflective operations that consume property names,
such as handler traps?

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


Re: Type of property names, as seen by proxy traps

2011-07-08 Thread David Herman
 I'm not sure. I briefly checked the private names proposal 
 http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects and I 
 think the detailed interaction with proxies still has to be fleshed out.

Sure, I'll be happy to work with you on this.

 The proposal does mention: All reflective operations that produce a property 
 name, when reflecting on a private name, produce the name’s .public property 
 instead of the name itself.
 
 Would the same hold for reflective operations that consume property names, 
 such as handler traps?

No, they would require the private name object. The idea here is that you need 
a reference to the private name to get access to its property. So you can't do 
any proxy operations on a private property if you don't have the private name 
object. But the proxy traps do not automatically hand out that reference to a 
handler trap, in case the trap didn't already have a reference to it (which 
would constitute a leak). Instead, it hands them the corresponding public key. 
This way, *if* the trap has a reference to the private key, it can identify 
which private name is being accessed. Otherwise, the trap can't conclude 
anything more than operation X was requested on *some* private name.

Dave

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


Re: Type of property names, as seen by proxy traps

2011-07-08 Thread Brendan Eich
On Jul 8, 2011, at 7:17 AM, David Herman wrote:

 The proposal does mention: All reflective operations that produce a 
 property name, when reflecting on a private name, produce the name’s .public 
 property instead of the name itself.
 
 Would the same hold for reflective operations that consume property names, 
 such as handler traps?
 
 No, they would require the private name object.

I don't think that's what Tom was asking about, though. The proposal may simply 
be unclear in using produce instead of consume since the proxy mechanism 
does not produce private names in any generative sense when one writes p[q] for 
proxy p and private name q.

Rather, the VM substitutes q.public for q when calling p's handler's relevant 
trap (getOwnPropertyDescriptor, get, ...). So there's no leak, as you note, and 
the owner of q is free to share it with trap implementations that should have 
access to it, so they can compare name == q.public, memoize in q.public in a 
weak map, etc.

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


Re: Type of property names, as seen by proxy traps

2011-07-08 Thread David Herman
Sorry, yes. Too early in the morning for me. :)

Indeed, handler traps are exactly the place where the system *produces* names 
and hands them to handler traps which consume them, and that's where it must 
produce a public key rather than a private name object.

Dave

On Jul 8, 2011, at 8:20 AM, Brendan Eich wrote:

 On Jul 8, 2011, at 7:17 AM, David Herman wrote:
 
 The proposal does mention: All reflective operations that produce a 
 property name, when reflecting on a private name, produce the name’s 
 .public property instead of the name itself.
 
 Would the same hold for reflective operations that consume property names, 
 such as handler traps?
 
 No, they would require the private name object.
 
 I don't think that's what Tom was asking about, though. The proposal may 
 simply be unclear in using produce instead of consume since the proxy 
 mechanism does not produce private names in any generative sense when one 
 writes p[q] for proxy p and private name q.
 
 Rather, the VM substitutes q.public for q when calling p's handler's relevant 
 trap (getOwnPropertyDescriptor, get, ...). So there's no leak, as you note, 
 and the owner of q is free to share it with trap implementations that should 
 have access to it, so they can compare name == q.public, memoize in q.public 
 in a weak map, etc.
 
 /be

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


Re: Type of property names, as seen by proxy traps

2011-07-08 Thread David Herman
And just to be clear, I meant produce in the sense of producer/consumer 
relationship on the trap functions, not in the generative sense.

Dave

On Jul 8, 2011, at 8:40 AM, David Herman wrote:

 Sorry, yes. Too early in the morning for me. :)
 
 Indeed, handler traps are exactly the place where the system *produces* names 
 and hands them to handler traps which consume them, and that's where it must 
 produce a public key rather than a private name object.
 
 Dave
 
 On Jul 8, 2011, at 8:20 AM, Brendan Eich wrote:
 
 On Jul 8, 2011, at 7:17 AM, David Herman wrote:
 
 The proposal does mention: All reflective operations that produce a 
 property name, when reflecting on a private name, produce the name’s 
 .public property instead of the name itself.
 
 Would the same hold for reflective operations that consume property names, 
 such as handler traps?
 
 No, they would require the private name object.
 
 I don't think that's what Tom was asking about, though. The proposal may 
 simply be unclear in using produce instead of consume since the proxy 
 mechanism does not produce private names in any generative sense when one 
 writes p[q] for proxy p and private name q.
 
 Rather, the VM substitutes q.public for q when calling p's handler's 
 relevant trap (getOwnPropertyDescriptor, get, ...). So there's no leak, as 
 you note, and the owner of q is free to share it with trap implementations 
 that should have access to it, so they can compare name == q.public, memoize 
 in q.public in a weak map, etc.
 
 /be
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant

Le 07/07/2011 13:11, Tom Van Cutsem a écrit :
2011/7/6 Andreas Rossberg rossb...@google.com 
mailto:rossb...@google.com


While putting together some test cases for Object.keys, I wondered: is
it intended that property names are always passed to traps as strings?


That is indeed the intent.

It seems like a reasonable assumption, but is not currently the case
everywhere (e.g. the default implementation for `keys' can violate
this assumption when passing names to this.getOwnPropertyDescriptor).


How so? The default implementation for the keys trap relies on the 
return value of the getOwnPropertyNames() trap, whose return value is 
coerced to an array of Strings.
The return value of the trap is. The return value of 
this.getOwnPropertyNames isn't.
With a pure mapping from internal methods to trap, the trap call and 
handler.trap (this.trap) are the same. However, with invariant 
enforcement, they are different. Type coercion is a such an invariant 
enforcement (that actually could be added to FixedHandler).


David



Cheers,
Tom

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org mailto: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: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 13:11, Tom Van Cutsem tomvc...@gmail.com wrote:
 2011/7/6 Andreas Rossberg rossb...@google.com

 While putting together some test cases for Object.keys, I wondered: is
 it intended that property names are always passed to traps as strings?

 That is indeed the intent.


 It seems like a reasonable assumption, but is not currently the case
 everywhere (e.g. the default implementation for `keys' can violate
 this assumption when passing names to this.getOwnPropertyDescriptor).

 How so? The default implementation for the keys trap relies on the return
 value of the getOwnPropertyNames() trap, whose return value is coerced to an
 array of Strings.

Not quite. The coercion is taking place in Object.getOwnPropertyNames,
but the default `keys' trap doesn't go through that, but instead calls
the trap directly. Moreover, it has to do it like that, because it
doesn't even have a reference to the proxy itself.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant

Le 07/07/2011 14:29, Andreas Rossberg a écrit :

On 7 July 2011 13:11, Tom Van Cutsemtomvc...@gmail.com  wrote:

2011/7/6 Andreas Rossbergrossb...@google.com

It seems like a reasonable assumption, but is not currently the case
everywhere (e.g. the default implementation for `keys' can violate
this assumption when passing names to this.getOwnPropertyDescriptor).

How so? The default implementation for the keys trap relies on the return
value of the getOwnPropertyNames() trap, whose return value is coerced to an
array of Strings.

Not quite. The coercion is taking place in Object.getOwnPropertyNames,
but the default `keys' trap doesn't go through that, but instead calls
the trap directly. Moreover, it has to do it like that, because it
doesn't even have a reference to the proxy itself.
However, if we assume that the getOwnPropertyNames trap is able to do 
type coercion on its output, there is no reason for the keys trap to not 
do that too, regardless of how it was implemented.


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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 14:32, David Bruant david.bru...@labri.fr wrote:

 However, if we assume that the getOwnPropertyNames trap is able to do type
 coercion on its output, there is no reason for the keys trap to not do that
 too, regardless of how it was implemented.

Yes, that's what I would propose, too. It's just a bit ugly that we
have to do that in two places now.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant

Le 07/07/2011 14:40, Andreas Rossberg a écrit :

On 7 July 2011 14:32, David Bruantdavid.bru...@labri.fr  wrote:

However, if we assume that the getOwnPropertyNames trap is able to do type
coercion on its output, there is no reason for the keys trap to not do that
too, regardless of how it was implemented.

Yes, that's what I would propose, too. It's just a bit ugly that we
have to do that in two places now.
Three if counting the enumerate trap for for-in loops. Regardless of 
ugliness, it's necessary. keys and enumerate are derived traps. They 
have a default implementation for developer convenience, however, 
developers could decide to reimplement the trap and the proxy engine 
implementation have to enforce types anyway. Each trap has to be guarded 
independently.
Derived traps as showed are written in JS for expository purposes. 
Engines will be free to optimize as they wish internally as long as the 
observed behavior is the same. Specifically, I think that type inference 
engines can be of a great help in ensuring that types are correct 
without having to pay the price of looking at every single element 
independently.


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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 15:09, David Bruant david.bru...@labri.fr wrote:
 Yes, that's what I would propose, too. It's just a bit ugly that we
 have to do that in two places now.

 Three if counting the enumerate trap for for-in loops. Regardless of
 ugliness, it's necessary. keys and enumerate are derived traps. They have a
 default implementation for developer convenience, however, developers could
 decide to reimplement the trap and the proxy engine implementation have to
 enforce types anyway. Each trap has to be guarded independently.
 Derived traps as showed are written in JS for expository purposes. Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.

True, but optimizing that actually is more tricky than you might
think, since in general it would change the semantics if an engine
decided to call toString only once. It has to make sure that none of
the names are objects, or at least none of their toString methods was
modified and they are all free of side effects.

 Specifically, I think that type inference engines can
 be of a great help in ensuring that types are correct without having to pay
 the price of looking at every single element independently.

I don't think that the type checks are the biggest cost. Doing the
actual conversion several times for those cases where the type is
_not_ string is potentially much more expensive.

I guess it's fine if programmers suffer for returning objects as
property names. But something like integers might be a valid use case.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Herman
 2011/7/6 Andreas Rossberg rossb...@google.com
 While putting together some test cases for Object.keys, I wondered: is
 it intended that property names are always passed to traps as strings?
 
 That is indeed the intent.

Unless they are private name objects, right?

Dave

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 16:12, David Bruant david.bru...@labri.fr wrote:
 Derived traps as showed are written in JS for expository purposes.
 Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.

 True, but optimizing that actually is more tricky than you might
 think, since in general it would change the semantics if an engine
 decided to call toString only once. It has to make sure that none of
 the names are objects, or at least none of their toString methods was
 modified and they are all free of side effects.

 Interesting.
 However, I'm not sure side-effects are a problem.
 -
 var o = {a:1, toString:function(){o.b = 12; return 'a'; }};
 console.log(o[o], o.b); // 1, 12 on Firefox 5
 -
 Here, o[o] triggers a side effect and that sound like the normal behavior.

I'm not sure I understand what your example is intended to show. But
consider this:

var i = 0
var o = {toString: function() { ++i; return a }
var p = Proxy.create({getOwnPropertyNames: function() { return [o] }, ...})
var k = Object.keys(p)
// What's the value of i now?

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Brendan Eich
On Jul 7, 2011, at 8:32 AM, Andreas Rossberg wrote:

 On 7 July 2011 16:12, David Bruant david.bru...@labri.fr wrote:
 Derived traps as showed are written in JS for expository purposes.
 Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.
 
 True, but optimizing that actually is more tricky than you might
 think, since in general it would change the semantics if an engine
 decided to call toString only once. It has to make sure that none of
 the names are objects, or at least none of their toString methods was
 modified and they are all free of side effects.
 
 Interesting.
 However, I'm not sure side-effects are a problem.
 -
 var o = {a:1, toString:function(){o.b = 12; return 'a'; }};
 console.log(o[o], o.b); // 1, 12 on Firefox 5
 -
 Here, o[o] triggers a side effect and that sound like the normal behavior.
 
 I'm not sure I understand what your example is intended to show. But
 consider this:
 
 var i = 0
 var o = {toString: function() { ++i; return a }
 var p = Proxy.create({getOwnPropertyNames: function() { return [o] }, ...})
 var k = Object.keys(p)
 // What's the value of i now?

Fresh tracemonkey tip js shell:

js var i = 0
js var o = {toString: function() { ++i; return a }}
js var p = Proxy.create({getOwnPropertyNames: function() { return [o] },
  getOwnPropertyDescriptor: function() { return {value:42} 
}})
js var k = Object.keys(p)
js i
1


Where would there be a double-conversion?

/be

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 17:58, Brendan Eich bren...@mozilla.com wrote:
 On Jul 7, 2011, at 8:32 AM, Andreas Rossberg wrote:

 On 7 July 2011 16:12, David Bruant david.bru...@labri.fr wrote:
 Derived traps as showed are written in JS for expository purposes.
 Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.

 True, but optimizing that actually is more tricky than you might
 think, since in general it would change the semantics if an engine
 decided to call toString only once. It has to make sure that none of
 the names are objects, or at least none of their toString methods was
 modified and they are all free of side effects.

 Interesting.
 However, I'm not sure side-effects are a problem.
 -
 var o = {a:1, toString:function(){o.b = 12; return 'a'; }};
 console.log(o[o], o.b); // 1, 12 on Firefox 5
 -
 Here, o[o] triggers a side effect and that sound like the normal behavior.

 I'm not sure I understand what your example is intended to show. But
 consider this:

 var i = 0
 var o = {toString: function() { ++i; return a }
 var p = Proxy.create({getOwnPropertyNames: function() { return [o] }, ...})
 var k = Object.keys(p)
 // What's the value of i now?

 Fresh tracemonkey tip js shell:

 js var i = 0
 js var o = {toString: function() { ++i; return a }}
 js var p = Proxy.create({getOwnPropertyNames: function() { return [o] },
                      getOwnPropertyDescriptor: function() { return {value:42} 
 }})
 js var k = Object.keys(p)
 js i
 1

 Where would there be a double-conversion?

Well, with the canonical fix to the spec we discussed further up the
thread (adding a conversion to string in the default trap for `keys')
there would (have to) be. So my concern was that that is perhaps not
the best fix, despite its simplicity.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant
Le 07/07/2011 18:05, Andreas Rossberg a écrit :
 On 7 July 2011 17:58, Brendan Eich bren...@mozilla.com wrote:
 On Jul 7, 2011, at 8:32 AM, Andreas Rossberg wrote:

 On 7 July 2011 16:12, David Bruant david.bru...@labri.fr wrote:
 Derived traps as showed are written in JS for expository purposes.
 Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.
 True, but optimizing that actually is more tricky than you might
 think, since in general it would change the semantics if an engine
 decided to call toString only once. It has to make sure that none of
 the names are objects, or at least none of their toString methods was
 modified and they are all free of side effects.
 Interesting.
 However, I'm not sure side-effects are a problem.
 -
 var o = {a:1, toString:function(){o.b = 12; return 'a'; }};
 console.log(o[o], o.b); // 1, 12 on Firefox 5
 -
 Here, o[o] triggers a side effect and that sound like the normal behavior.
 I'm not sure I understand what your example is intended to show. But
 consider this:

 var i = 0
 var o = {toString: function() { ++i; return a }
 var p = Proxy.create({getOwnPropertyNames: function() { return [o] }, ...})
 var k = Object.keys(p)
 // What's the value of i now?
 Fresh tracemonkey tip js shell:

 js var i = 0
 js var o = {toString: function() { ++i; return a }}
 js var p = Proxy.create({getOwnPropertyNames: function() { return [o] },
  getOwnPropertyDescriptor: function() { return 
 {value:42} }})
 js var k = Object.keys(p)
 js i
 1

 Where would there be a double-conversion?
 Well, with the canonical fix to the spec we discussed further up the
 thread (adding a conversion to string in the default trap for `keys')
 there would (have to) be. So my concern was that that is perhaps not
 the best fix, despite its simplicity.
No, with the current keys default trap (calling
this.getOwnPropertyNames()) there is no double conversion. Only one at
the exit of the keys trap. There would be 2 conversions if the keys
trap had the proxy argument (based on
http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
and if internally, the default keys trap was calling
Object.getOwnPropertyNames(proxy) (which would call the trap and do
type coercion).

But the current implementation and a type coercion only when going out
of traps would do double-conversion.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant
Le 07/07/2011 18:24, David Bruant a écrit :
 Le 07/07/2011 18:05, Andreas Rossberg a écrit :
 On 7 July 2011 17:58, Brendan Eich bren...@mozilla.com wrote:
 On Jul 7, 2011, at 8:32 AM, Andreas Rossberg wrote:

 On 7 July 2011 16:12, David Bruant david.bru...@labri.fr wrote:
 Derived traps as showed are written in JS for expository purposes.
 Engines
 will be free to optimize as they wish internally as long as the observed
 behavior is the same.
 True, but optimizing that actually is more tricky than you might
 think, since in general it would change the semantics if an engine
 decided to call toString only once. It has to make sure that none of
 the names are objects, or at least none of their toString methods was
 modified and they are all free of side effects.
 Interesting.
 However, I'm not sure side-effects are a problem.
 -
 var o = {a:1, toString:function(){o.b = 12; return 'a'; }};
 console.log(o[o], o.b); // 1, 12 on Firefox 5
 -
 Here, o[o] triggers a side effect and that sound like the normal behavior.
 I'm not sure I understand what your example is intended to show. But
 consider this:

 var i = 0
 var o = {toString: function() { ++i; return a }
 var p = Proxy.create({getOwnPropertyNames: function() { return [o] }, ...})
 var k = Object.keys(p)
 // What's the value of i now?
 Fresh tracemonkey tip js shell:

 js var i = 0
 js var o = {toString: function() { ++i; return a }}
 js var p = Proxy.create({getOwnPropertyNames: function() { return [o] },
  getOwnPropertyDescriptor: function() { return 
 {value:42} }})
 js var k = Object.keys(p)
 js i
 1

 Where would there be a double-conversion?
 Well, with the canonical fix to the spec we discussed further up the
 thread (adding a conversion to string in the default trap for `keys')
 there would (have to) be. So my concern was that that is perhaps not
 the best fix, despite its simplicity.
 No, with the current keys default trap (calling
 this.getOwnPropertyNames()) there is no double conversion. Only one at
 the exit of the keys trap. There would be 2 conversions if the keys
 trap had the proxy argument (based on
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
 and if internally, the default keys trap was calling
 Object.getOwnPropertyNames(proxy) (which would call the trap and do
 type coercion).

 But the current implementation and a type coercion only when going out
 of traps would do double-conversion.
not. would not do double-conversion, sorry.

 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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread Andreas Rossberg
On 7 July 2011 19:35, David Bruant david.bru...@labri.fr wrote:
 No, with the current keys default trap (calling
 this.getOwnPropertyNames()) there is no double conversion. Only one at
 the exit of the keys trap. There would be 2 conversions if the keys
 trap had the proxy argument (based on
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
 and if internally, the default keys trap was calling
 Object.getOwnPropertyNames(proxy) (which would call the trap and do
 type coercion).

 But the current implementation and a type coercion only when going out
 of traps would do double-conversion.
 not. would not do double-conversion, sorry.

I thought the fix we were discussing was changing the `keys' default trap from

keys: function() {
  return this.getOwnPropertyNames().filter(
function (name) { return
this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
}

to something along the lines of

keys: function() {
  return this.getOwnPropertyNames().filter(
function (name) { return this.getOwnPropertyDescriptor('' +
name).enumerable }.bind(this));
}

That would fix passing non-strings to the getOwnPropertyDescriptor
trap, but introduce double conversions when you invoke Object.keys.
I'm not sure what alternative you are proposing now.

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


Re: Type of property names, as seen by proxy traps

2011-07-07 Thread David Bruant
Le 07/07/2011 20:52, Andreas Rossberg a écrit :
 On 7 July 2011 19:35, David Bruant david.bru...@labri.fr wrote:
 No, with the current keys default trap (calling
 this.getOwnPropertyNames()) there is no double conversion. Only one at
 the exit of the keys trap. There would be 2 conversions if the keys
 trap had the proxy argument (based on
 http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy)
 and if internally, the default keys trap was calling
 Object.getOwnPropertyNames(proxy) (which would call the trap and do
 type coercion).

 But the current implementation and a type coercion only when going out
 of traps would do double-conversion.
 not. would not do double-conversion, sorry.
 I thought the fix we were discussing was changing the `keys' default trap from

 keys: function() {
   return this.getOwnPropertyNames().filter(
 function (name) { return
 this.getOwnPropertyDescriptor(name).enumerable }.bind(this));
 }

 to something along the lines of

 keys: function() {
   return this.getOwnPropertyNames().filter(
 function (name) { return this.getOwnPropertyDescriptor('' +
 name).enumerable }.bind(this));
 }

 That would fix passing non-strings to the getOwnPropertyDescriptor
 trap, but introduce double conversions when you invoke Object.keys.
 I'm not sure what alternative you are proposing now.
I was completely not thinking about this one. Sorry for the
misunderstanding.

I would be in favor to not do the conversion at all for
this.getOwnPropertyDescriptor. I think that derived trap default
implementation should be lightweight (no conversion if a trap calls
another handler method). Type coercion can be implemented manually (like
anything else). I think it's good to give as default behavior
(implemented by engines, so hopefully more efficient) the one that is
the most consistent with internal methods expetations (for instance
[[GetOwnProperty]] expects a string as a name, for instance)

The way I view it, it's up to the handler author to write his/her traps
consistently. If he/she decides to return objects on a
this.getOwnPropertyNames call, then if the spec says that this function
will be called without type coercion, he/she has to implement
this.getOwnPropertyDescriptor accordingly.
But that's just my opinion.

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