On Mar 27, 2011, at 10:31 PM, Brendan Eich wrote:
>
> That strawman is essentially functional record update for setting __proto__
> AKA [[Prototype]], although it reads backwards compared to FRU in ML-family
> languages. Those languages put the update on the right, often linked using
> 'with' (hah!).
It can be viewed that way, although I doubt that the vast majority of current
JS programmers would recognize it as such...but that could change over time.
In general, I favor putting what is typically the longer operand second.
Otherwise, the operator and right operand tend to get lost after a long left
operand. In the case of functional record update, it appears that in most
usage the update part is longer:
e with {a=4, b=2}
because the existing object is likely to be referenced via an identifier
binding or function call and the update values are more likely to be some sort
of longer literal.
The most common case for proto probably is the opposite as the "record" that is
being modified is the operand that is more likely to be a long literal form:
return myProto proto {
a: 1,
b:2,
m1: function () (},
m2: function () {}
};
Personally, I think the above makes it more obvious that we are returning an
object with an explicitly specified prototype than the following:
return {
a: 1,
b:2,
m1: function () (},
m2: function () {}
} proto myProto;
However, I acknowledge that in the above the object literal is probably the
more important part of the expression and that having it first emphasizes that
part.
It may be a toss up, I need to think about whether there are any other
constructors in ES with which we should be striving for consistency. Perhaps,
function() {}.bind(e) is one.
>
> As you note in the strawman, this enables proto-presetting for a number of
> built-in classes, not just Object and Array.
>
> I'm warming up, modulo the backward sense of the connective (also, you need a
> [no LineTerminator here] to the left of ''proto'' in the productions).
> Thinking outside the box, indeed.
yep, we want that to be a contextual operator keyword so we need to be careful
about ASI.
>
> Dmitry's suggestion of #proto or a similar sigil-distinguished name makes me
> wonder, though: could we have FRU via the spread operator *and* proto
> presetting without adding a funky [no LineTerminator here] proto infix
> operator?
>
> var original_o = ...;
> var o = {#proto: p, ...original_o};
>
> Given this, if you don't have an original_o to specialize (say, a RegExp or
> other built-in that can't be created via an initialiser), then of course
>
> var o = {#proto: p, key: val, ...};
or
var f= {#proto: p, ...function () {}};
var r= {#proto: p, .../[a-z]/};
var a={#proto: p, ...[1,2,3,4]);
???
For the cases of setting the prototype of a literal function/regexp/array I
really prefer forcing the literal into immediate proximity of the prototype.
eg,
var f = p proto function () {};
or even
var f = {#proto: p, ...function() {}}
is much better than:
var f0 = function() {};
//arbitrary lines of code
var f = {#proto, ...f0};
If nothing else that latter is going to require significantly more analysis in
the front-end to avoid creating two function objects.
Using spread in this way requires generalizing its semantics to copy not just
properties but also magic internal properties.
Finally, I really don't want to have to use the
{#proto: p, ...[1,2,3,4]}
or
var a0 =[1,2,3];
var a = {#proto: p, ...a0};
forms for arrays.
[#proto: p, 1,2,3]
might be ok, but at the TC39 meetings there were concerns expressed about comma
counting.
>
> should be supported.
>
> So, infix operators or magic property names?
>
> For classes, at any rate, it seems to me that On the Outside and Declarative
> may be at odds, since initialisers are expressions. More below on why.
I'm kinda moving away from thinking that object literal and class declaration
forms need to use common syntax.
>
>
>>> The strongest case for extending initialiser syntax is that it is "nearly
>>> declarative" today. That suggests strongly making the extension fully
>>> declarative, i.e., not usable as an expression. And that, all else equal
>>> (never is, but:) says to consider class D extends B {...}. My 2 cents.
>>
>> I don't think "declarative" should not be equated with "not usable as an
>> expression " or introduces a lexical binding.
>
> It's not clear that classes need to bind their names, or even need names. I
> believe that some on TC39 want non-generative, nominal run-time types via
> classes. Others may want generative expressions.
>
> The consistent #1 request from users that I've heard over the years, most
> recently in my blog comments, has been for a declarative form of JS's
> prototypal object-oriented pattern. This conventionally means a new binding.
> It's generative if you nest it in an outer function, which is not a problem,
> but usually it is not nested, or else nested only in an outer IIFE (aka the
> module pattern).
that's the request I'm most interesting in satisfy with a "class" declaration.
In that scenario "class" is close to meaning "constructor function" or just
"function". That is why in my proposal
class Foo {};
is defined to mean almost exactly the same thing as
function Foo() {};
(but things start to change when you put something between the brackets) and
anonymous classes exist as an analog to function expressions.
>
>
>> Both function declarations and function expressions are both declarative
>> definitions of functions
>
> Here is a bit of a nit, but calling both declarative even though one is an
> expression, not a declaration, sounds like a contradiction, or a redefinition
> of "declarat{ive,ion}".
I'm using "declarative" more (but not exactly) in this sense: "In computer
science, declarative programming is a programming paradigm that expresses the
logic of a computation without describing its control flow.[1] Many languages
applying this style attempt to minimize or eliminate side effects by describing
what the program should accomplish, rather than describing how to go about
accomplishing it.[2] This is in contrast with imperative programming, which
requires an explicitly provided algorithm."
http://en.wikipedia.org/wiki/Declarative_programming
I would say that:
({a,x,b:y,c:z})
is declarative while
{let obj = new Object;
obj.a=x;
obj.b=y;
obj.c=z;
obj}
is not. It's imperative. They are both generative in that they create new
objects whose initial state can only be determine at the time they are
evaluated.
My usage has nothing to do with binding forms but my terminology seems to be
causing confusing with binding forms in this context. I don't immediately
have a another term at hand for a non-imperative, non-binding construction
expression.
>
> More substantive: if we want to enable optimizations and conveniences via
> syntax for the prototypal pattern, then declarations win, especially if they
> come with some ahead-of-time semantics, as top-level function declarations
> evaluated in a compile-and-go scenario do. Thanks to the order of function
> and then var declaration processing when entering an execution context, such
> a scenario supports the compiler pre-binding top-level functions.
I'm trying to relate this statement to the original "strongest case" comment
above and I'm having a hard time. I probably something more concrete would
help.
>
> You're right that expressed as well as declared (whether top-level or not)
> forms could be supported. The question for classes is whether we would ever
> want an anonymous or named class expression. Just because 'function' can do
> that does not mean that 'class' must.
A key thing about the proto operator proposal (and different from my earlier
meta properties proposals) is that it is trying to specifically address only
the use case of providing an explicit [[Prototype]] for objects created using
literal construction forms (object literals, array literals, regexp literals,
function expressions). It does not currently address classes at all. If both
this proto operator proposal and a class syntax gets adopted we would certainly
want to revisit whether there can/should to be an commonality between the two.
It's too early to tell.
Allen
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss