Object.methods
On 23.08.2011 21:32, Allen Wirfs-Brock wrote:
The rough convention we were following for ES5 was that Object.* functions that were expected to be used in application layer code had short imperative names like keys, create, freeze, etc. Functions that were expected to be primarily used in meta layers of framework or other reflective purposes have long descriptive names.
I see, thanks for clarifications Allen, it makes sense. Though... the consistency also matters ;)
The wordiness of the names is largely a function of the degrees of variation that might be consider. For example, own vs. all properties or property names vs property descriptors. getOwnPropertyDescriptor/getOwnPropertyNames are the winners in that category. defineProperty/defineProperties don't need the "own" because properties are always defined on a specific object and don't need "descriptor" because there are no similar operations that don't use descriptors.
Yes.
And what about this method Object.getMethods(...),
Object.getMethodNames(...). Do we need it? I think it can be useful
(since methods can be non-enumerable, and Object.keys(...) won't help,
and after Object.getOwnPropertyNames(...) you have to manually filter
them when typeof
is "function")
Dmitry.
On 24.08.2011 0:39, Allen Wirfs-Brock wrote:
On Aug 9, 2011, at 1:03 PM, Dmitry A. Soshnikov wrote:
And what about this method Object.getMethods(...), Object.getMethodNames(...). Do we need it? I think it can be useful (since methods can be non-enumerable, and Object.keys(...) won't help, and after Object.getOwnPropertyNames(...) you have to manually filter them when
typeof
is "function")I'm don't really see the that they are needed enough to build these in when they can be synthesized pretty easily. What is the justification for these and not others such as getAccessorProperties, getDataProperties, getNonWritableProperties, etc.
Maybe, why not? Object.methods
is just standard in some languages
(e.g. Ruby, foo.instance_methods
). Yes, all of yours listed above
could be either built-in or self-implemented, don't know how often they
are needed IRL. This topic follows the recent near topic with
doc-comments of functions. The same, playing with a new language in
console it's the best just to type e.g. foo.methods
(like in Ruby) and
to see directly the list of methods to which the object responds.
Besides, perhaps they can be used in other meta-level programming, but
the initial idea seems studying the language in the console and playing
with objects (not sure though whether it's a sound reason to be accepted
for standardization).
Dmitry.
The rough convention we were following for ES5 was that Object.* functions that were expected to be used in application layer code had short imperative names like keys, create, freeze, etc. Functions that were expected to be primarily used in meta layers of framework or other reflective purposes have long descriptive names. The wordiness of the names is largely a function of the degrees of variation that might be consider. For example, own vs. all properties or property names vs property descriptors. getOwnPropertyDescriptor/getOwnPropertyNames are the winners in that category. defineProperty/defineProperties don't need the "own" because properties are always defined on a specific object and don't need "descriptor" because there are no similar operations that don't use descriptors.
On Aug 9, 2011, at 1:03 PM, Dmitry A. Soshnikov wrote:
And what about this method Object.getMethods(...), Object.getMethodNames(...). Do we need it? I think it can be useful (since methods can be non-enumerable, and Object.keys(...) won't help, and after Object.getOwnPropertyNames(...) you have to manually filter them when
typeof
is "function")
I'm don't really see the that they are needed enough to build these in when they can be synthesized pretty easily. What is the justification for these and not others such as getAccessorProperties, getDataProperties, getNonWritableProperties, etc.
On Aug 9, 2011, at 2:05 PM, Dmitry A. Soshnikov wrote:
On 24.08.2011 0:39, Allen Wirfs-Brock wrote:
I'm don't really see the that they are needed enough to build these in when they can be synthesized pretty easily. What is the justification for these and not others such as getAccessorProperties, getDataProperties, getNonWritableProperties, etc.
Maybe, why not?
Object.methods
is just standard in some languages (e.g. Ruby,foo.instance_methods
). Yes, all of yours listed above could be either built-in or self-implemented, don't know how often they are needed IRL. This topic follows the recent near topic with doc-comments of functions. The same, playing with a new language in console it's the best just to type e.g.foo.methods
(like in Ruby) and to see directly the list of methods to which the object responds. Besides, perhaps they can be used in other meta-level programming, but the initial idea seems studying the language in the console and playing with objects (not sure though whether it's a sound reason to be accepted for standardization).Dmitry.
One difference between Ruby and JavaScript is that Ruby has a formal concept of method and JavaScript does not. Whether a JS data property whose value is a function is considered to be a method or function valued instance variable is highly situational. Similarly, I can also imagine an interpretation that only inherited function valued data properties are considered to be methods or that methods need to be non-writable and non-enumerable. Adding super bindings also complicates things. Perhaps, only properties with function values that have super bindings to the object or one of its prototypes should be considered a method. Which of these definitions should be use for a built-in Object.methods.
I'm all for rich interactive environments for working with JavaScript and such environments do need to access or infer metadata about JavaScript code. However, I don't necessarily think the a REPL model is the best exemplar for such an environment. Also there can be real problems with exposing too much program metadata directly to the application layer. I've had lots of experience with Smalltalk environments where this was the case and it leads to a muddling of the metalayers and the application layers of a system because many developers don't understand the concepts of stratification well enough to know which methods are not really appropriate for use in application logic.
On 24 August 2011 01:07, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
Also there can be real problems with exposing too much program metadata directly to the application layer. I've had lots of experience with Smalltalk environments where this was the case and it leads to a muddling of the metalayers and the application layers of a system because many developers don't understand the concepts of stratification well enough to know which methods are not really appropriate for use in application logic.
That is true, although you cannot really blame the programmers when the language designers already muddled it up. That very sin has been committed in JavaScript, for example, by putting arbitrary reflective methods into innocent intrinsics like Object. I guess programmers would be much less likely to abuse them if they had a separate home in an object/module explicitly named Meta, Reflect, or something.
On 24.08.2011 3:07, Allen Wirfs-Brock wrote:
On Aug 9, 2011, at 2:05 PM, Dmitry A. Soshnikov wrote:
On 24.08.2011 0:39, Allen Wirfs-Brock wrote:
I'm don't really see the that they are needed enough to build these in when they can be synthesized pretty easily. What is the justification for these and not others such as getAccessorProperties, getDataProperties, getNonWritableProperties, etc.
Maybe, why not?
Object.methods
is just standard in some languages (e.g. Ruby,foo.instance_methods
). Yes, all of yours listed above could be either built-in or self-implemented, don't know how often they are needed IRL. This topic follows the recent near topic with doc-comments of functions. The same, playing with a new language in console it's the best just to type e.g.foo.methods
(like in Ruby) and to see directly the list of methods to which the object responds. Besides, perhaps they can be used in other meta-level programming, but the initial idea seems studying the language in the console and playing with objects (not sure though whether it's a sound reason to be accepted for standardization).Dmitry.
One difference between Ruby and JavaScript is that Ruby has a formal concept of method and JavaScript does not.
(JFTR, moreover, Ruby has only methods in this cases, that is, accessors for private instance vars, but anyway it doesn't matter much)
I propose to use definition of a method as a "property which value is a function". That's after all, is the same as from ES5 spec:
ECMA-262-5:
4.3.27 method function that is the value of a property.
Whether a JS data property whose value is a function is considered to be a method or function valued instance variable is highly situational.
For the simplicity and because instances themselves can store methods and override them from parent's prototypes, I think the simplest version is again description from 4.3.27.
Similarly, I can also imagine an interpretation that only inherited function valued data properties are considered to be methods or that methods need to be non-writable and non-enumerable.
No, no, it's not required IMO. Because of dynamics, instances may have
own methods -- why not? And they are still methods, that is some action
which is activated and has this
as the instance.
Adding super bindings also complicates things. Perhaps, only properties with function values that have super bindings to the object or one of its prototypes should be considered a method. Which of these definitions should be use for a built-in Object.methods.
Object.getMethods(object) ->
var methods = {}; do { for (var [propertyName, value] in items(Object.getOwnPropertyNames(object)) if (typeof value == "function") { methods[propertyName] = value; } } while (object = Object.getPrototypeOf(object));
return methods;
Objects.getMethods(foo).createBar.doc // shows description of createBar function on foo object.
Don't know. Just one-of possible ways. E.g. it may consider only own methods.
I'm all for rich interactive environments for working with JavaScript and such environments do need to access or infer metadata about JavaScript code.
Absolutely. Currently ES doesn't even have a good console to try the
language. Once again, these two things as: (1) good auto-complete of
property names which is shown by pressing tab
after dot property
accessor, and (2) the ability to get help information on the function
directly from the console -- help(parseInt) -> "Converts a string into a
num..." makes learning the language much quicker and fun.
I think you should think on implementing the sample version of ES -- the ES itself and to spread it as downloadable binaries from the ecmascript.org. Then people will just be able (1) to run it and pay in the console learning the methods and properties of object, getting the documentation right from here and (2) to attach the engine to favorite editor and call it right from the editor by just pressing F5 and getting output to the editors console back. There's no need to install Firefox or Chrome first, go to their consoles, write there with inconvenient way (or to copy-paste code from convenient editor to the inconvenient Firebug's console and run).
Because now, to compile e.g. SpiderMonkey, it is required long process with installing Mozilla-build, then to install many patches to VS (because my 2005 compiler isn't supported anymore), etc. It doesn't matter much of course, I can handle it. But it would be the best if newcomers could just download ECMAScript (for Windows, Mac, Linux) and just execute it. And already in the console to play with it and to get the help directly and introspect meta-information, such as methods, etc.
Python did it. It's learned in a week max. Why not ES?
However, I don't necessarily think the a REPL model is the best exemplar for such an environment.
Maybe, don't know. But the internal information on functions it's IMO very good idea which implemented by Python. Moreover, that's said, the good possibilities for auto-suggest and auto-complete based on the doc-comment.
Also there can be real problems with exposing too much program metadata directly to the application layer.
OTOH, yes, true.
I've had lots of experience with Smalltalk environments where this was the case and it leads to a muddling of the metalayers and the application layers of a system because many developers don't understand the concepts of stratification well enough to know which methods are not really appropriate for use in application logic.
Regardless that unstratified meta-level is not a good idea, only it allows to write the code in the shortest ways and without much of syntactic "noise" and "garbage". But, seems we're talking about stratified method -- Object.methods(obj), and not about obj.method.
However, that's said, I also don't see big practical applications of this exact Object.methods(...), so comments and the cases are welcome, so we have to think whether we even need it.
Dmitry.
On Aug 24, 2011, at 2:09 AM, Andreas Rossberg wrote:
On 24 August 2011 01:07, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
Also there can be real problems with exposing too much program metadata directly to the application layer. I've had lots of experience with Smalltalk environments where this was the case and it leads to a muddling of the metalayers and the application layers of a system because many developers don't understand the concepts of stratification well enough to know which methods are not really appropriate for use in application logic.
That is true, although you cannot really blame the programmers when the language designers already muddled it up. That very sin has been committed in JavaScript, for example, by putting arbitrary reflective methods into innocent intrinsics like Object.
ES5 (originally ES3.1) did not have the luxury of waiting for modules. That's too bad, but we're better off making progress, even if one cost was polluting Object. WiB (yes, I know what that means, I have the scars).
Inevitably, with a standards body gating evolution of the language, we will do things backward. Five years ago I mentioned macros and Crock said "can't we do them now, avoid hardcoding new syntax?" Macros are still out there well beyond ES6.
I guess programmers would be much less likely to abuse them if they had a separate home in an object/module explicitly named Meta, Reflect, or something.
JS has unstratified reflection in its special forms, from day 1. obj[prop], for (prop in obj), and (later, day 3) 'in' are examples.
The paltry ES3 additions to Object.prototype (hasOwnProperty, propertyIsEnumerable, and the singularly useless isPrototypeOf) were more muddling, in my view.
Using my multiverse viewer, I see that the universes where JS had B&D-style segregation of obj[prop] and for (prop in obj) into some Reflect object-as-module from day 1 all ended in premature sad-user heat death. Seriously!
On Aug 24, 2011, at 2:09 AM, Andreas Rossberg wrote:
On 24 August 2011 01:07, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
Also there can be real problems with exposing too much program metadata directly to the application layer. I've had lots of experience with Smalltalk environments where this was the case and it leads to a muddling of the metalayers and the application layers of a system because many developers don't understand the concepts of stratification well enough to know which methods are not really appropriate for use in application logic.
That is true, although you cannot really blame the programmers when the language designers already muddled it up. That very sin has been committed in JavaScript, for example, by putting arbitrary reflective methods into innocent intrinsics like Object. I guess programmers would be much less likely to abuse them if they had a separate home in an object/module explicitly named Meta, Reflect, or something.
I totally agree. Rather than adding lots of new Object.* methods I'd generally prefer that we start placing future metaprogramming APIs into various modules.
I do, however, think that we will need to add Object.defineMethod in ES.next.
(BTW, I've been experimenting with what the API for a Mirrors-based reflection module might look like: www.wirfs-brock.com/allen/posts/228 )
I'm about to propose
Object.methods(obj)
meta-method (orObject.getMethods(obj)
). Unfortunately naming convention is inconsistent (arrgh!) --Object.keys
(hello, Ruby and Prototype.js) vs. Object.getOwnPropertyNames (o_O hello Java), so the method name can be chosen later.But the idea is to get the properties (or their names) which are methods on the object.
Proposed:
var foo = { bar: function () {}, proto: {baz: function () {}} };
Object.getMethods(foo) -> {bar: function () {}, baz: function () {}}
Object.getOwnMethod(foo) -> {bar: function () {}}
Object.getMethodNames(foo) -> ["bar", "baz"]
Object.getOwnMethodNames(foo) -> ["bar"]
Of course it can be easily implemented in JS itself just filtering the Object.getMySummerVacationWasLongOwnPropertyNames or Object.keys(...), but directly in the engine it will be more efficient.
Dmitry.