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 ES.next.
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 s
tate 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".
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss