Okay, it seems I don’t agree with the only use case you gave for redifining 
getPropertyNames, but, well it doesn’t mean the feature should be dropped if 
nobody else is complaining about that. 

For your curiosity :
[[Since “fixing” getPropertyNames would involves returning the properties of an 
object and its prototype chain, you can already fix the problem with a proxy on 
which you can define both getOwnPropertyNames and the prototype (that can be 
another proxy if there’s really a big bug that involves a bad 
getOwnPropertyNames on the prototype itself). BTW, if you want to fix an 
implementation, it’s because you expect some consistent behavior for the 
getPropertyNames function, meaning that an inconsistent behavior should not be 
allowed because you would like to fix it if it once existed in the wild.]]

In fact, it seems that the ES5 specification defines both [[GetProperty]] and 
[[GetOwnProperty]] on objects, and does not explicitely say that ECMAScript 
host objects should comply with the default implementation of [[GetProperty]]. 
Additionnaly, the specification has consistency requirements for 
[[GetOwnProperty]] but not for [[GetProperty]]. So it seems legal to allow a 
proxy to redefine both [[GetProperty]] and [[GetOwnProperty]]. It’s not good to 
allow that, from my point of view, but it’s possible. 

While I’m rereading the spec another time, I notice there’s however a notice 
that specify that “Named properties of the [[Prototype]] object are inherited 
(are visible as properties of the child object)”meaning that a [[GetProperty]] 
implementation could not be dramatically different of getOwnProperty(p) || 
prototype.getProperty(p). Anyway, there’s no way to be sure a supplied 
ECMAScript function asserts the constraints defined in the specification.

François



From: David Bruant 
Sent: Monday, January 24, 2011 12:53 AM
To: François REMY 
Cc: es-discuss ; Mark S. Miller 
Subject: Re: [ES Harmony Proxies] Different points on proxies ground

As a starter, I remind that I am not direclty involved in the proposal. What I 
say about the proposal is ony my view and interpretation of what I read 
(proposal, blog articles, tutorial, slides) and watch (presentations).
I do not make any decision.

Le 23/01/2011 21:36, François REMY a écrit : 
  Thanks for your response. 

  I understand your point. You say that we should open up everything, because 
authors will be responsible users and because freedom brings more possibilities.
I am sorry, but that's not what I said. I haven't said that we should open 
everything. I said that I agreed with the idea of providing more power to the 
users to drive language innovation instead of having a group of people in an 
ivory tower defining standards.
I have said your last point: proxies brings power/potential/possibilities. 
About proxy users, what I have said is "It's up to the people who are going to 
use proxies to be careful to be coherent with what they pretend to do". I'm not 
saying that they will do it. I know they are human. I know some are going to 
misinterpret and misunderstand a lot of things. That's also the reason why I am 
currently working on writing the proxy documentation 
(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy) 
which is very likely to be the first thing people go to when they'll have 
questions and need examples.
No one can prevent humans from misusing something. We can work on trying to 
reduce the unintended misuses, though.


  I’m not against opening everything, but does it have a sense ? I’m also 
involved in the www-style mailing list, and we’ve seen there many attempts to 
bring new things to the CSS language. Many times, however, the proposals are 
not followed by true changes, and even some initially appraised specifications 
sometimes finish in the tourment. Because use cases where not correctly 
defined, and because the specification has become hazardous and difficult to 
implement, while the main use cases could require something a lot simpler.
I don't know all the use cases, but I have seen a couple:
1) Being able to emulate host objects in JavaScript.
1) 1) Even with ES5, the DOM (and its ECMAScript binding) cannot be implemented 
in ECMAScript. One example I see is data-* attributes. I need to check, but the 
way I understand it, an element object needs to have its "data-*" properties in 
sync with the .getAttribute("data-*")/.setAttribute("data-*", value) for all 
possible DOMString replacing "*". I may be wrong, but it is just impossible to 
do in ES5
1) 2) Even with ES5, it is impossible to emulate IE DOM (I have read it, but 
have no proof. If anyone reading does, feel free to jump in to provide an 
example).
1) 3) NodeList. They are live objects 
(http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-536297177). They are 
currently implemented with host objects. With pure ES5, impossible to 
implement. Possible with proxies.


2) Some security features like membranes 
(https://developer.mozilla.org/en/XPConnect_security_membranes) 
(http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane) 
requires proxy to be written at all (and easily). Once again, I have no formal 
proof of it, but seeing the implementation gives me confidence in the fact that 
it's not possible without proxies (or equivalently-powerful mecanism).

3) Fixing web browsers's mess. If you haven't seen it yet, I invite you to read 
this : http://ejohn.org/blog/the-dom-is-a-mess/ . I think that it would be 
ridiculously easier to wrap+replace a lot of native DOM objects using a 
forwarding proxy to fix them. This is what jQuery and all JS (DOM) library is 
all about. Proxies will give them the opportunity to fix the mess in browsers 
(that implement proxies) things they currently may not be able to do since host 
objects can differ from regular objects by having not emulable semantics.

I don't know any other use case, but unlike CSS, ECMAScript goes beyond the web 
browser (http://ejohn.org/blog/the-world-of-ecmascript/). Or rather should I 
say, for the Firefox case, it goes "inside" the web browser which is another 
usage of ECMAScript.


  We should consider here the questions we need to answer each time we’re going 
to change anything to a language: What are our goals when doing this addition? 
Which use cases are we supporting? Will it really bring more good than bad? Is 
there not something we can do to make things easier? Without use cases, 
implementing a feature is an hazardous action, which don’t lead to the expected 
results. Among the use cases presented of the site, none would benefit from a 
separate getPropertyName (or has or ...) implementation.
If Object.getPropertyNames(document.getElementById('myId')) is bogus (for 
instance inconsistent with getOwnPropertyNames + prototype names), I want to be 
able to programmatically write a library in JS that fixes the bug (and I think 
I can if I use a forwarding proxy wrapper around DOM elements). If you only 
allow me to redefine Object.getOwnPropertyNames, I am left aside with my 
impossibility to fix the bug.

If the proxy implementation is correct and the trap set complete, I can face 
ANY bug on host objects. I think I could even face bugs in regular objects 
(maybe not any bug since handlers are themselves regular objects and a lot of 
things would certainly require regular objects to be emulated).

4) Being able to fix ANY bug on host objects. That sounds like a unique use 
case that would justify everything that is currently in the proxy proposal.



  While I remove my proposal to replace the true prototype by a function, I’m 
still staying strong on what I said. Is there any use case that could justify 
to allow to redefine the fundamental meaning of functions like 
Object.getPropertyNames? Does our users really want to worry about possible 
inconsistencies of getOwnPropertyNames and getPropertyNames ? If yes, what is 
the reason ?

  I suppose that you realize that by allowing has and (chained) hasOwn to have 
different results, you forces users to rely on their own methods to determine 
if a property exists? Or, at least, you assume that code written today may not 
work as expected tomorrow because it used hasOwn and not has. With such a 
change, we are consciently making the core functionnalities of ES5 potentially 
inconsistents.
I am sorry, but I think there something I don't understand. Proxies are an 
addition to ECMAScript. They do not change the language, they do not change the 
semantics of regular objects. The only thing proxies do is providing a new sort 
of object-typed /things/ that can be used but do not behave like regular 
objects. Regular objects remain completely unchanged.
As said in a talk (http://www.youtube.com/watch?v=A1R8KGKkDjU starting at 
18'00'').
"The API doesn't allow you to redefine the semantics of existing objects". All 
the things that were true in ES5 remains. Proxies are just a usage of what is 
written in ES5 8.6.2 Object Internal Properties and Methods right under table 
8: "Every object (including host objects) must implement all of the internal 
properties listed in Table 8.". This is done here : 
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics#semantics_of_proxies

The inconsistency that proxies could bring isn't in ES5. It is in people's 
expectations and current (mis)understanding of what ECMAScript objects are. 
They are going to use proxies, they'll make a mistake once, will learn from 
some doc/the spec itself/blog articles/whatever and know that what they used to 
call objects was actually one case of what ECMAScript objects actually are (ES5 
section 8.6).



  Just because it sounds beautiful to open up everything. What amazes me is 
that, however, everybody seems conscient that redefining === and typeof is not 
a good thing. And with no other arguments than consistency. Saying that people 
are good developers, that they will be attentive to avoid breaking anything, 
all this is pure utopy. People are humans. They do errors. They are not 
omniscient. Even more, some are intentionally evil. The best help you could 
give to developers is to keep things simple and help them making good code by 
avoiding things they are not likely to do but that could confuse them. Because 
getPropertyNames is not used often, and a mistake in the code written for its 
accessor may well stay unnoticed for years, but have important consequences 
after.

  Yes, I meant that by removing some of the consistency of ECMAScript, you’re 
moving to a dangerous way. But my point is not that it should not be done. 
Discovering the United States was the reward of a dangerous journey. However, 
nobody should engage in a dangerous way if it has no reason to do so. So, I 
repeat my question: what are the use cases we’re wanting to solve by exposing 
access to both getOwnPropertyNames and getPropertyNames ? I humbly think they 
are no use cases. It’s up to everyone to show they are use cases. But it should 
be done.

  By adding possible inconsistency to ECMAScript, this spec seems to fail at 
their own goals. No matter what you’re saying, the driving forces of the 
proposal are meant to be simplicity and consistency (following ES5 
conventions). Power isn’t written down anywhere on the spec. It’s not clear to 
me how being able to define both getPropertyName and getOwnPropertyNames is a 
gage of consistency. Consistency is to say that getPropertyNames returns a list 
containing the property of an object and its prototype chain. It’s simple. 
There’s no exception. There should be no other defintion of getPropertyNames 
that should be on the table if there’s not a reason for it (sorry for 
repeating, but it’s important to me).

  On the other side, a proxy could redifine getOwnPropertyNames. Well, the 
properties we’re talking in getOwnPropertyNames are their own properties. It 
seems normal the proxy can choose to expose those or not, or event invent them. 
But it should not have an impact on the prototype properties when 
getPropertyNames is called.

  Maybe the best thing I can do to end up this mail is to cite Allen 
Wirfs-Brock :
    For these reasons, any major proposal to extend JavaScript needs to be 
critically examined for its impact upon the existing JavaScript object mode.  
If the extension requires a major change to the object model, it may be 
difficult for programers to understand and use.  For implementers, even seemly 
simple object model changes may require significant redesign of existing 
optimization mechanisms and the invention of new techniques.

I think I need the context, because I am not sure of what "object model" means. 
If it means regular object semantics, then fine, proxies aren't changing it. 
If it means ES5 section 8.6.2 table 8, then fine, proxies aren't changing the 
table, they are only an "instanciation of the table" which isn't a change to 
the table itself or to other "table instanciations" like regular or host 
objects are.
Proxies are implemented in FF4 and currently being used internally, they 
haven't required "a significant redesign of existing optimization mechanisms 
and the invention of new techniques" that I would be aware of 
(https://bugzilla.mozilla.org/show_bug.cgi?id=546590).

Regards,

David


  I’m not asking anything different. If there’s a reason to allow the redifine 
getPropertyNames, it should be done. But is there a reason ? This is my 
question.
  Regards,
  François
  From: David Bruant 
  Sent: Sunday, January 23, 2011 7:29 PM
  To: François REMY 
  Cc: es-discuss ; Mark S. Miller 
  Subject: [ES Harmony Proxies] Different points on proxies ground (was: 
Fundamental trap definition)

  Hi,

  Since your response does not really answer my point (definition of 
fundamental traps), I take the responsibility to change the title and provide 
an answer.
  I am not an ECMAScript expert and not involved in the TC-39 commitee, but 
here are my answers.

  Overall, I think (I may be wrong) that you're confusing two different 
concepts which are :
  - ECMAScript objects which are "regular objects", a set of properties with 
all the semantics that we are all used to and which any programmer can create 
through "new Object()" (or "{}" for lazy people like myself);
  - The Object Type (ECMAScript 5 section 8.6) in the broad sense which 
includes "regular objects", "host objects" and maybe soon proxies.

  The former are an "instanciation" of the latter with the semantics that is 
defined in ES5 section 8.12 (Algorithms for Object Internal Methods). Proxy 
will be one with programmer-defined semantics.

  As far as I understand proxies, they are not designed to provide garantees 
toward acting the same way as regular objects do (even for the prototype chain 
behavior). They aim at allowing the programmer to FULLY redefine in ECMAScript 
the semantics of operations on object besides some core operations (typeof, 
===, Object.getPrototypeOf, instanceof, am I forgetting one?) which are some 
core garantees that define the object type (ES5 section 8.6) identity.
  Actually, as I am writing it, I am realizing that only "typeof" and "===" are 
really part of the object type identity. 
  But it can be read 
(http://wiki.ecmascript.org/doku.php?id=harmony:proxies#interaction_with_instanceof)
 that 'Object.getPrototypeOf' ([[Prototype]]) isn't trapped because it would 
provoke an inconsistant behavior for instanceOf
  and 'instanceof' have been decided to not be trapped because of a security 
issue.

  I think that the main idea behind proxies isn't consistency. It's power. In 
"Harmony of my dreams" (http://brendaneich.com/2011/01/harmony-of-my-dreams/), 
Brendan Eich's quotes Guy Steele on language growth:
  "We need to put tools for language growth in the hands of the users.". First 
i agree with this and second of all, proxies are going in that direction. 
  I share your concern that it's a powerful and then dangerous feature for 
consistency's sake, but "with great power, comes great responsibility". It's up 
to the people who are going to use proxies to be careful to be coherent with 
what they pretend to do. And there are already some mecanisms that helps 
consistency like derived traps or even the Default Proxy forwarding handler 
proposal 
(http://wiki.ecmascript.org/doku.php?id=strawman:proxy_defaulthandler&s=forwarding)

  David

  Le 23/01/2011 17:43, François REMY a écrit : 
  Moreover, should a Proxy really have a prototype ?
  I mean, what’s the point about having a prototype, since the “get” method can 
return everything you would like for any property ?

  I think getProtototypeOf should be defined as a new trap. And its default 
behaviour should be to return null (or Object.prototype, but I think null is 
the intented behavior of a proxy).

  On the other hand, overriding getPropertyNames should not be allowed. 
getPropertyNames should *always* return the concatenation of the properties 
returned by getOwnPropertyNames() and by 
getPrototypeOf(this).getPropertyNames(). It makes no sense otherwhise. 

  I understand that we may want to redefine the way an ECMAScript Object can 
handle the native commands, but I’m strongly against anything that can conduce 
to illogical results (if there’s not an use case that justify it, naturally). 
The definition of getPropertyNames is clear and being able to redefine it 
locally seems me wrong. A proxy can modify is own behavior, not the behavior of 
the ES engine. Being able to have getPropertyNames and getOwnPropertyNames 
returning incompatible results is somewhat hurting me. Is there any reason we 
should allow that ? Any use case ?

  I’m issuing the same concerns for the “has” trap. It think it should not be a 
trap. It should always return hasOwn(key) || prototype.has(key). Each one of 
hasOwn and prototype can be tuned by the proxy, but not the “has” itself. We’re 
not removing features, but we prevent bad usage of it. Whatever the user code 
do, the ‘has’ behavior will stay logical.

  Another thing I don’t quite understand is the difference between “keys” and 
“enumerate”. If there’s no strong difference, it should be the same trap (same 
logic: enumerate should return the concatenation of this.keys and 
this.prototype.keys). Having two different but similar traps will cause 
confusion. Maybe there’s a need for this difference however. I just didn’t 
understand why such a difference should exist, but at least I see more possible 
usages than the first three traps I “contested”. 

  Anyway, if we should retain only one thing from the discussions we already 
have seen on the Proxy hub, is that it’s a great feature, but one that still 
needs some work before implementation ;-)

  Regards,
  François

  From: David Bruant 
  Sent: Sunday, January 23, 2011 4:24 PM
  To: es-discuss 
  Cc: Mark S. Miller 
  Subject: [ES Harmony Proxies] Fundamental trap definition

  Hi,

  I am wondering if getPropertyDescriptor and getPropertyNames fundamental 
traps shouldn't rather be derived traps since they could have a pretty 
straightforward default implementation.
  One implementation of getPropertyNames could be :
  -------------------------- 
  Object.getPropertyNames = function(o){
      var objectToInspect;
      var result = [];

      for(objectToInspect = o; 
          objectToInspect !== null; 
          objectToInspect = Object.getPrototypeOf(objectToInspect))
      {
              result = 
result.concat(Object.getOwnPropertyNames(objectToInspect)); 
      }

      return result.removeDuplicates(); // the removeDuplicates method is made 
up, but you get the point
  }
  --------------------------
  This seem to fit the proposal 
(http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api&s=getpropertydescriptor)
 expectations). This could be also the default getPropertyNames trap 
implementation.

  I haven't really seen a strong definition of what fundamental traps are in 
the proposal. On Mark Miller's e-mail 
(https://mail.mozilla.org/pipermail/es-discuss/2011-January/012601.html) is 
written:
  [a trap is fundamental if] there is no coherent default behavior to fall back 
to that would be defined in terms of the remaining traps. (please tell me if I 
misinterpret what you meant)
  If we're going with this definition, then getPropertyDescriptor and 
getPropertyNames should probably be derived traps since they can clearly be 
defined thanks to other traps (respectively getOwnPropertyDescriptor and 
getOwnPropertyNames as I showed above) which seems to be coherent fallback 
behavior.
  Instead of a formal definition, this could be a rational for deciding what is 
a fundamental trap and what isn't.

  In the 5 remaining traps (getOwnPropertyDescriptor, getOwnPropertyNames, 
defineProperty, delete, fix), I don't see any that could be defined thanks to 
the others. They seem to be also the fundamental actions that one can perform 
on a single object:
  Property-wise:
  - create/configure a property (defineProperty)
  - delete a property (delete)
  - retrieve a property (getOwnPropertyDescriptor. Can be used to separate the 
create and configure cases of defineProperty)
  Property-set-wise:
  - retrieve the property set (getOwnPropertyNames. More can be found later on 
each property with getOwnPropertyDescriptor)
  - prevent further extension (and optional reconfigurations for seal and 
freeze)(fix)
  The prototype can be retrieved thanks to Object.getPrototypeOf (which cannot 
be trapped for consistency purposes) and all actions can be performed by 
climbing the prototype chain.

  Any thoughts on the fundamental trap definition?
  Or on the idea of turning getPropertyDescriptor and getPropertyNames into 
derived traps with the suggested definition?

  David

------------------------------------------------------------------------------
  _______________________________________________
  es-discuss mailing list
  [email protected]
  https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to