1. I don't like the imperative approximations of a declarative API.
Since we're designing new language features, approximations
should not be necessary.
There have been suggestions to interpret '<|' declaratively,
and to avoid the special case for function rhs, ie, to interpret
(p <| obj) simply as a structural representation of an object with
un-nameable '[[prototype]]' field containing p.
You mean ditching function RHS completely or just not having it to
specially treat LHS being function as well?
Neither. Currently, <| sets the [[prototype]] field of the RHS object,
and -if the RHS is a function literal- also specifies the [[prototype]]
field of objects generated from it. I suggest to remove that special
case for function RHS.
What were the arguments against this?
2. JS claims to be prototype-based but the 'prototype'-field really
points to shared traits, while the actual cloning of prototypes into
It's probably too late to rename it to instanceTraits (I find the name
'prototype' unhappy, too)
objects happens in the constructor functions. A deviation
from Self (if I recall that correctly), it is a source of confusion.
If we combine the two points (cloning happens in the constructor,
<| declares 'prototype' field), we get something like:
var Blah = function(){
return BaseClass <| {
a: function(){},
b: function(){}
}
}
I'd say no to this -- ES is classless, but not true prototype oriented. I
would keep the constructor-function-as-the-class-and-factory-at-once. Even
if it is not optimal, but I think it is the cornerstone of ES object
model.
If I'm not mistaken, the code above is valid in the current <| proposal
(one might want to add a level of indirection to share a and b).
I'm not changing the constructor function approach, but the <| proposal
makes it possible to specify the object [[prototype]] directly, without
the indirection through the constructor function 'prototype'.
If working with functions wasn't so cumbersome in JS, and if <| wasn't
limited to literal RHS (by making a shallow copy of the RHS, if necessary),
the [[prototype]] setting could easily be abstracted out of the constructor,
by function composition, without having to special-case function RHS in <|:
function compose(f,g) { .. }
function extend(proto,constr) {
return compose(function(obj) { return proto <| obj }, constr)
}
var Blah = extend(BaseClass, function(){
return { a: function(){}, b: function(){} }
})
Of course, this would raise the question of whether the pattern is
simple enough for code analyzers and optimizers to detect.. But mostly,
the special case in <| is an artifact of function manipulation being too
inconvenient in JS, and of <| being limited to literals (which is an
artifact of object cloning being considered tricky).
This reminds me a lot of old-style Lego vs more flexible construction sets:
there were way too many pre-fabricated components in Lego, because
the base set wasn’t flexible enough. As a Lego kid, I was envious of other
construction kits that had no built-in hurdles against 3d or mobile
structures.
Is our ideal a language with few, simple components, from which all
features we want can be built, or a language with lots of non-simple
prefab components for common use cases?
The latter can paper over limitations in the core language, and can be
quite successful in spite of its awkwardness. If we want the former, we
need to simplify components were we can, and remove any obstacles
in the core language that gives rise to non-simple proposals.
Claus
P.S.: I would not be against <| being much more declarative, even if you
deny function RHSes from being <|-able (but why? function may want to have
prototype other than Function.prototype, too; and not only for
"class-inheritance"); but only if there would be other possibility to do
the "class-inheritance", that, double chain (constructor->constructor as
well as prototype->prototype).
function Sub (params) extends Super { body }
for example.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss