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

Reply via email to