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