On Sat, Mar 17, 2012 at 1:09 PM, Allen Wirfs-Brock <al...@wirfs-brock.com>wrote:

>
> On Mar 17, 2012, at 2:03 AM, Russell Leggett wrote:
>
> Given the recent go at finding alternative syntax for the <| operator, I
> thought about it and decided to split the functionality between creating
> "instances" using alternative prototypes, and the other side of the fence
> making reusable extended objects easier to make.
>
> Its a little long so I threw it in a gist: https://gist.github.com/2056771
>
>
> I've already replied WRT : vs <| in another message so this is about the
> rest of the ideas in your gist.
>
> Some of this feels like it is circulating  back to things we already
> discussed, for example at
> http://www.mail-archive.com/es-discuss@mozilla.org/msg10365.html
>
> I also wanted to point out that there is another way to express object
> instantiation with arbitrary [[Prototype]].  It is the new <object>
> operator as described in
> https://mail.mozilla.org/pipermail/es-discuss/2011-September/016736.html
>
> Essentially,
>      let proto = { ... };  //some literally defined object
>      let instance = proto <| { };  //instance is new object with no own
> properties who [[Prototype]] is proto
>
> could be expressed as
>      let instance = new proto; //instance is new object with no own
> properties who [[Prototype]] is proto
>
> The only difference is that |new proto| would also apply an initialization
> function (proto's constructor property) on the new instance.
>

Yes, I remember this discussion, and I thought about it before posting, but
I think it's orthogonal. |new proto| is about using objects like
constructor functions + prototypes as "object exemplars", but what I'm
trying to advocate is one of the biggest use cases which is using
enhanced/altered versions of the default prototype (by extension, not
mutation) combined with the literal to create a new instance.

This is the way that I was thinking about it:

    {} same as Object:{}
    [] same as Array:[]
    "" same as String:""
    function(){} same as Function:function(){}
    ...

So when I want to make a new enhanced String/Object/Array, I would just do

    class Email extends String {
        get isValid:function(){...}
        ...
    }

and then I can make a new one like

    let email = Email:"russell.legg...@gmail.com";

This breaks it up very cleanly. I suppose this could be too much emphasis
for a given use case, but I find it very easy to reason about. I mean,
doesn't this really break things down into the use cases better? You want
to make a special kind of Array? Use extends. You want to make a new one
using literal syntax? Use : (or :: or :::).


>
> Other than that, the only real difference I see is that the "magic" you
> are applying regarding functions is different from that defined for <| but
> it is still treated as a special case. You magic is that if the LHS is a
> function you always use the value of its prototype property (BTW, what if
> it doesn't have one) as the [[Prototype]] value.   so if you say:
>    (functtion f1() {}) : function f2() {}
> the [[Prototype]] of f2 will be f1.prototype and f2 will not inherit at
> all from Function.prototype.  This doesn't seem right.
>

There is no special magic in : for functions, it is consistent across all.
I'm just trying to break down the use cases a little better. I covered your
example with a different form:

    function sub(arg1,arg2) extends sup {
        super(arg1,arg2);
        //more stuff here
    }

But I would also point out that if we get down to real world cases, we need
to start thinking about real cases. Why am I extending one function from
another function? Are we trying to add extra methods? Are we trying to take
advantage of super? I find the proposal a little lean on real use cases for
function other than the class pattern, which I think is better handled by
actual class syntax. If it is to be able to make functions that are derived
from an enhanced function, then I think it should follow the same pattern I
gave above for Email.

    class MyFunc extends Function {
        curry(...args){...}
    }

    //using my proposed short form from the gist
    let test = MyFunc:(x,y,z){
        return x + y + z;
    };

    let curr1 = test.curry(1);
    let curr2 = curr1.curry(2);
    let total = curr2(3);
    console.log(total); //6


>
> If you just think about <| (or :) as an instantiation operator you still
> have to take into account what it means to have "function (,,,) {,,,}" on
> the RHS. The issue is that such a function express is actually
> instantiating two objects and they both need to get their [[Prototype]]
> values set to something reasonable.   I think that my <| definition
> supplies a more reasonable (fewer new user surprises) then your :
> definition.
>

I think your solution makes it easier to reason about extending constructor
functions using <|, but as I was saying in the gist, I think we should
leave that to class. If I have a function on the RHS of :, what I really
want is a new function (not class) of a certain type, potentially with
different methods.

- Russ


>
> Allen
>
>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to