Using Object Literals as Classes

Allen Wirfs-Brock allen at
Sat Mar 17 11:13:29 PDT 2012

On Mar 16, 2012, at 11:42 PM, Kevin Smith wrote:

> Hi Allen,
> Thanks for taking the time to read and respond.  I've read your reply in detail and I feel like it deserves a point-by-point response, but I think the following might get us on the same page more quickly.
> The important point to consider is that I'm *not* comparing this:
> A.)
>    let Blah = BaseClass <| function() {
>    }.prototype.{
>       a() {}
>       b() {}
>    }.constructor.{};
> to this:
> B.)
>     function Blah()
>     Blah.prototype = Object.create(BaseClass.prototype);
>     Blah.prototype.a = function() {};
>     Blah.prototype.b = function() {};
> but rather, to what I currently use, which is this:
> C.)
>     var Blah = new Class({
>         extends: BaseClass,
>         new: function() {},
>         a: function() {},
>         b: function() {},
>         // also
>         static: { staticA: 123 }
>     });
> There's no question that the object literal pattern A is superior to B.  But for me, that's a false comparison.  It's got to be better than C (or another similar class API), or I won't use it.

Perhaps, not a "false" comparison but a different comparison...

While you wouldn't use A because it can't express the full semantics of C, that doesn't mean that many users who currently have to write B wouldn't prefer to be able to write A.

I don't believe that simply allowing a non-literal value as the RHS of <| would be an adequate solution to your problem (or at least to all similar problems) because all that <| really does is set the [Prototype]] property of a new object.  Object.create already lets you do that and we have also talked about supporting Object.extend as an alternative way to express the same thing.

As an alternative you suggest that declarative class syntax would make your library unnecessary.  However, I assume that the same caveat applies for that syntax as you are  applying to the object literal pattern.  You would only use the declarative syntax if it supported the full class semantics you have chosen to use for your library. For example, I note that your library seems to have support for either/or multiple inheritance or mixins (which isn't totally clear from the examples).  I assume that you wouldn't use declarative syntax that did not have equivalent features but neither  is likely to be in any class syntax that we can reach agreement on in time for

What you are essentially doing with your library is defining an internal DSL for expressing definitions for classes that conform to your preferred semantics. The linguistic  atoms of your DSL are ES expression elements.  Some self contained expression elements, such as constants,  function expressions with no free variables, and object/array literal containing such elements work pretty well as DSL atoms.  Expression elements that are not self contain, such as function expressions that need to capture a reference to a private name or a pre-instantiated object whose [[Prototype]] is already set  don't work as well. You are depending upon the ES language to "compile" the function expressions into runtime entities that you will directly use within the class abstractions your DSL constructs. However, in some cases you really need to intercede before that compilation takes place so your can remap the meaning of the function expression to match your semantics (eg, handling private state references where you define the implementation model of the state).  There is currently no way for you to do this, other than preprocessing the ES source code).

Supporting internal DSL is an interesting use case but not one that is explicitly stated as a harmony goal.  However, supporting library writers is a goal. In some ways, "what do you need to build a better DSL for defining your classes" is something that may be easer to address than "what class syntax and semantics would satisfy you and every other ES programmer and library/framework provider".


More information about the es-discuss mailing list