Design principles for extending ES object abstractions

Brendan Eich brendan at
Fri Jul 8 15:59:49 PDT 2011

On Jul 8, 2011, at 3:49 PM, Allen Wirfs-Brock wrote:

> On Jul 8, 2011, at 2:58 PM, Brendan Eich wrote on the thread using Private name objects for declarative property definition. :
>> But whatever the class syntax, and the disposition of private in class and even classes in, I agree we should expect private declarative and expression forms to work the same in object initialisers and in classes.
>> It would be good to get everyone buying into this private-means-property-with-private-name-key-everywhere agreement.
> I wanted to generalize this a bit.  In designing "classes" and other new ES abstractions there are a couple design principles that I think it is important that we follow:
> 1) Everything works with plain objects.
> Objects (and functions) are the primitive abstraction mechanisms of ES.
> Any new functionality we add must be applicable and available to plain vanilla singleton objects.
> Anti-example:  super keyword that is only available in a class declaration
> Acceptable solution: super keyword is available for both class declaration and object literals.
> 2) Anything that can be done declaratively can also be done imperatively.
> Imperative/reflective object construction is a power feature of ES that has been widely exploited by everyday developers as well as  metaprogrammers.
> Any new object capabilities that we make available via declarative  constructs must also be available via an imperative API.
> Anti-example: functions definitions using super keyword may only occur within an object literal or class declaration.
> Acceptable solution: Object.defineMethod can be used to bind an externally defined function that uses the super keyword to a specific object.
> I don't expect that anybody will significantly disagree with either of these principles.  But I think it is good to explicitly articulate them and make sure we have agreement one them. Sometimes we spend a lot of time discussing an idea that doesn't or can't conform to these principles.


Note that generators as we've prototyped them have the same imperative/reflective constructor as functions: Function. You just use "yield" in the body string. In working on generators for standardization, we proposed requiring "*" after "function" at the head to distinguish (for readers) generator functions from non-generator functions, since "yield" in the body is sometimes far removed from the start of the function.

But the stronger reason for "function*" as mandator generator syntax introducer came when we considered "yield*" ("yield from" in Python's PEP380): the utility of a zero-iterations basis case for a sub-generator. As Dave noted, otherwise you'd have to write "function* () {if (false) yield;}" or some such.

Does this mean we need a distinguished generator function constructor, e.g. Function.createGenerator? Probably so, for the stronger (zero-iterations, empty generator basis case) and for symmetry. Not a big deal but something to consider.

In any case, I like the generalizations you make here.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list