Hello,

I'd like to clarify the question about approach used in ECMA-262-5 regarding the code design for new methods of Object constructor.

I've read the section "Attribute Control API Design and Rationale" of "Proposed ECMAScript 3.1 Static Object Functions: Use Cases and Rationale" document: http://wiki.ecmascript.org/lib/exe/fetch.php?id=es3.1%3Aes3.1&cache=cache&media=proposals:proposal_to_refocus_tc39-tg1.pdf

I of course understand that now it is already too late to speak about it, because specification is already published. But nevertheless, maybe there is some hope to change something in new versions.

I think that approach used in ECMA-262-5 for new object methods contradicts ES nature. Of course, cases mentioned in that section of the document are correct and variations with "propertyIsDeletable", "propertyMakeEnumerable" as well as using a bit vector for handling property attributes (the descriptor) looks long and worse. So with these points everything's OK, they go without saying and can be omitted.

The point from that list with separation of Meta and App levels is interesting. But from this viewpoint all other methods of objects can be treated as meta-methods (such as "hasOwnProperty", "getPrototypeOf" and even "toString"). As well as e.g. bracket notation for property accessors which allows to access dynamic property names -- which is also kind of meta programming.

Accepted rules for new object methods -- that they should be directly in "Object" constructor instead of "Object.prototype" led to that now we have three (!) syntactically different approaches for the *same* semantically entity -- using methods of objects. These are:

- Object.keys();
- Object.get<SomeThing>();
- and the "old" approach such as foo.isPrototypeOf(bar);

I understand that "Object.keys()" is a kind of backward compatibility. But with what? With some js-libraty (in particular case I guess with "Prototype.js")?

First, the design of this method contradicts approved approach with "get" prefix (the second bullet), such as e.g. "getOwnPropertyNames".

Secondly, that is more essential, as ECMAScript uses the same semantics for the dot and bracket notations of property accessors, "keys" name can be improper. Because ES doesn't separate "keys/array indexes/properties", here all of them are "properties".

Thirdly, if to leave this "keys" and other similar "getters", maybe there was a sense to make them as real getters then? For example, o.keys, just like a.length (where "o" and "a" -- Object and Array instances accordingly). For what that useless call expression in this non-ideological "Object.keys()" method? And it still seems strange that it is just a "backward compatibility" with some library but not with previous version of language. In Ruby from which this "keys" methods was borrowed to "Prototype.js" there is separation in semantics of bracket and dot notations -- so there are "keys" in this case, but not "properties". In ES, I repeat, there is no such discrimination, so this "Object.keys()" looks odd for ES in contrast with all other new methods with "get" prefix.

Regarding the second bullet, all that "getters" (which are functions) also could be made as real getters:

o.ownProperties; // instead of Object.getOwnPropertyNames(o)

or "o.ownPropertyNames" if confusing that "property" isn't just a name, but property object with its descriptor. But this case isn't so essential, as is following.

Look at this (trivial, non-real, abstract) example:

var o = Object.freeze(
  Object.seel(
    Object.defineProperties(
      Object.create(proto),
      properties
    )
  )
);

And compare it with the following one:

var o = Object.create(proto)
  .defineProperties(properties)
  .seel()
  .freeze();

I know that we can define properties together with "Object.create", repeat -- this example is abstract. But it is obvious that the first example is harder to read and this repetition of "Object. - Object. - Object." with forced indention looks (in my opinion) worse.

Of course, we can provide own aliases for all that new methods and place them in "Object.prototype", like e.g. this one: http://gist.github.com/367080/ But this is just a compromise. Although, I prefer to use it in own projects improving the code reuse and avoiding this long repetitions of "Object. Object. Object." and similar. You talked about "long lines" in code when thinking about "propertyMakeEnumerable", but using this approach you provide also that long lines forcing to use this useless repetition of "Object." every time. Yeah, "propertyIsEnumerable" can be of course removed in some future (more radical) version, which will leave all old approaches (as Python did for 3.* version where some features are completely incomparable with 2.* versions -- and this is a good step for progress and do not carry all the time this old stuff).

Separating of "meta" and "app" of course is a good thing. But it is debatable what can be treated as "meta" level in this case. This cite from the mentioned above document looks really strange:

"/Object.prototype the methods would be part of the public interface of every application object in a program. As such, they need to be understood by every developer, not just library designers./"

Very strange cite. So, if I (and all) understand it correctly, all these new "meta" methods are just for library designers and should be (if possible) abstracted from "casual developer"? But of course it is not so, and all these methods will be used in every future code. Did you mean that user-defined object should contain only user-defined properties (with own invariants to be separated from other objects) and be like a simple hashtables without prototypes?

If any object can provide its string representation (using delegated "toString" from the prototype), why cannot it then get its "keys" using the same delegated approach? Why this action should be done by some "meta" (?) function? I think that "Object.prototype" /taking into account that in current API we can control [[Enumerable]] property/ is a good place for all base methods/properties of any object.

By the way, it is also petty that there's no ability to change prototype and there is only "get" function for that; __proto__ extension in this case was better.

Of course I do not blame ES5 or something. And this letter isn't an appeal all to change everything, of course not. But I just want to know what other members think about that new /design/. Maybe I do not see some very useful consequence of this new approach? I think it is as important as technical parts. Will you continue to develop the language in this stylistics? If so, we should change our approaches and ideology of ES-programming too.

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

Reply via email to