Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
Brendan Eich bren...@mozilla.com wrote:
 We already have good motivation for :: anyway, as sugar for bind. This
gives relief to the OO side of the expression problem trade-off by allowing
lexical bindings to be composed with method calls -- beautiful. No third
scope axis / lookup parameter!

Yeah, but this doesn't solve the original problem nearly as well IMO since
it's suddenly different from a normal method call. Having a different call
operator for scoped extension methods or method invocation seems very
confusing and counter intuitive for developers.

If I have to remember different invocation mechanics I kind of lost already
and I don't have the polymorphism I wanted. I completely agree with Allen
here.

Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 Now, what might be useful would be :: that has approximately this
semantics ... `   _method ? _method : shuffle}.call(myArray);`

What if the Array has the method further up the prototype chain - like on
Object.prototype and we extend it on Array.prototype? Not to mention that
the performance issues that plagued adding it to the normal invocation
repeat here.

On Mon, Oct 14, 2013 at 11:14 PM, Brendan Eich bren...@mozilla.com wrote:
 Right, that is a cost we always consider. Syntax can't be polyfilled.
Once shipped at scale cross-browser, it ends to be forever.

I've actually went around facebook groups with every day JavaScript
developers yesterday. Probably mostly ones that don't know how to read the
spec (even the really nice and clear ES5 one), but are working as full time
JavaScript developers.

Most of the people I talked to did not seem to appreciate having a breaking
syntax change in order to have scoped extension methods. This is still very
preliminary (~40 people) but I'd really like to get a stronger sense of
what more every day developers think. I'll check around and I'll return
with more significant data.

 You mean the use of 'this.constructor' to make generic Array methods that
create array results in ES1-5 create appropriate subclass instances?

Yeah, I think that's pretty cool - and I agree that if we can get away with
it it's totally worth it :)


On Mon, Oct 14, 2013 at 11:14 PM, Brendan Eich bren...@mozilla.com wrote:

 Definitely deep waters here, not one simple thing. Appreciate your
 interactions.

 Benjamin (Inglor) Gruenbaum wrote:

  But there were design issues too. ... user confusion or complexity
 remains an objection.

 Yes! This is the thing that bothers me /most/ right now about scoped
 extension methods. Introducing additional syntax to the language seems like
 a _huge_ objection to me, the fact that it's another thing to teach
 programmers and another thing to keep in mind when figuring out scopes when
 reading new code is a big deal in my opinion.


 Right, that is a cost we always consider. Syntax can't be polyfilled. Once
 shipped at scale cross-browser, it ends to be forever.


  Rick and Domenic pointed out to me that one of the bigger use cases I
 thought having scoped extension methods solves - extending a native object
 and not having to re-implement methods seems to be already solved by the
 clever way in the new spec and is under work. There are still interesting
 problems I think this solves but I'm really not convinced any more that
 adding the extra syntax is worth it.


 You mean the use of 'this.constructor' to make generic Array methods that
 create array results in ES1-5 create appropriate subclass instances?

 I still thought that was a breaking change on the web, which we were not
 sure we could get away with. But I agree with you it helps, a lot. Yet, it
 doesn't solve the use-cases at which the SOE strawman was aimed.

 /be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Generic Bundling

2013-10-15 Thread David Bruant

Le 14/10/2013 23:25, Brendan Eich a écrit :

Jorge Chamorro wrote:

The only work around for that is making as few requests as possible.


+∞, +§, and beyond.

This is deeply true, and a hot topic with browser/network-stack 
engineers right now.
It ought to be with software engineers as well and it's one of the 
reason why promise pipelining [1] is so appealing.


David

[1] http://erights.org/elib/distrib/pipeline.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Generic Bundling

2013-10-15 Thread David Bruant

Le 14/10/2013 23:20, Jorge Chamorro a écrit :

On 14/10/2013, at 22:11, David Bruant wrote:


You already can with inlining, can't you?

Yes and no:

-It's much more complicated than pre zipping a bunch of files and adding a ref 
attribute.
-It requires additional logic at the server side, and more programming.
Not really. If there was a need for lots of people, people would have 
come up with an open source grunt task already (or any other open source 
tooling).
The fact that people haven't tried too hard may also be an indication 
that bundling isn't such a pressing need.


With the appropriate tooling, it could be as simple to inline in an HTML 
as it is to gzip (2 clicks for each).


With tooling being such a hot topic these days (so many talks on tooling 
and automation in confs!) and the MIT-licence culture around it, I feel 
we, web devs, should start considering asking less from the platform and 
more from the tooling.



-It's not trivial always: often you can't simply concatenate and expect it to 
work as-is (e.g. module scripts).
-You might be forcing the server to build and/or gzip (á la PHP) on the fly = 
much more load per request.

This is equally true from zip-bundling, no?


-Inlined source isn't always semantically === non-inlined source = bugs.

True. It's admittedly easy to escape with decent discipline.


It would also be very interesting to know if you had .zip packing, would you be 
inlining?

... yeah ... good point, I probably wouldn't :-)

David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Andreas Rossberg
On 14 October 2013 22:10, Benjamin (Inglor) Gruenbaum ing...@gmail.com wrote:
 But there were design issues too. ... user confusion or complexity remains
 an objection.

 Yes! This is the thing that bothers me most right now about scoped extension
 methods. Introducing additional syntax to the language seems like a _huge_
 objection to me, the fact that it's another thing to teach programmers and
 another thing to keep in mind when figuring out scopes when reading new code
 is a big deal in my opinion.

Arguably, the _syntactic_ complexity is not huge. It is almost benign,
compared to the _semantic_ complexity.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
On Tue, Oct 15, 2013 at 12:50 PM, Andreas Rossberg rossb...@google.com
 wrote:

  Arguably, the _syntactic_ complexity is not huge. It is almost benign,
 compared to the _semantic_ complexity.

Agreed. I have a bit of a problem articulating my thoughts clearly through
this medium being new. The problem with introducing additional syntax to
have scoped extension methods to the language is mostly the semantics
scoped methods introduce by introducing the extra type of scope and not the
extra rule in the language grammar.

Even the syntax on its own sounds like a huge deal though, it's one more
thing to teach every programmer learning the language JavaScript and an
extra bit of cognitive overload.


On Tue, Oct 15, 2013 at 12:50 PM, Andreas Rossberg rossb...@google.comwrote:

 On 14 October 2013 22:10, Benjamin (Inglor) Gruenbaum ing...@gmail.com
 wrote:
  But there were design issues too. ... user confusion or complexity
 remains
  an objection.
 
  Yes! This is the thing that bothers me most right now about scoped
 extension
  methods. Introducing additional syntax to the language seems like a
 _huge_
  objection to me, the fact that it's another thing to teach programmers
 and
  another thing to keep in mind when figuring out scopes when reading new
 code
  is a big deal in my opinion.

 Arguably, the _syntactic_ complexity is not huge. It is almost benign,
 compared to the _semantic_ complexity.

 /Andreas

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Andreas Rossberg
On 15 October 2013 03:09, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 I still don't get why so many JS programmer with a FP orientation want  to do 
 things with the |this| binding.   |this| is for us OO geeks, if you are doing 
 FP you don't need it.

Well, 'this' comes up because you cannot avoid having to interface
with OOish APIs that conflicts with FPish composition patterns. For
example, you'd like to be able to do something like

  array.map(String.prototype.toLowerCase)

But map expects a function, while toLowerCase is only available as a
method. So unless you rewrap all relevant APIs in functional style you
have to deal with 'this' in one form or the other, and going back and
forth is not pretty with what JS currently offers. (Mind you, a bind
operator does not even address this particular example.)

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Mark S. Miller
On Tue, Oct 15, 2013 at 3:39 AM, Andreas Rossberg rossb...@google.comwrote:

 On 15 October 2013 03:09, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
  I still don't get why so many JS programmer with a FP orientation want
  to do things with the |this| binding.   |this| is for us OO geeks, if you
 are doing FP you don't need it.

 Well, 'this' comes up because you cannot avoid having to interface
 with OOish APIs that conflicts with FPish composition patterns. For
 example, you'd like to be able to do something like

   array.map(String.prototype.toLowerCase)


Using 
http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming

var bind = Function.prototype.bind;
var uncurryThis = bind.bind(bind.call);

array.map(uncurryThis(.toLowerCase))





 But map expects a function, while toLowerCase is only available as a
 method. So unless you rewrap all relevant APIs in functional style you
 have to deal with 'this' in one form or the other, and going back and
 forth is not pretty with what JS currently offers. (Mind you, a bind
 operator does not even address this particular example.)

 /Andreas
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett
On Tue, Oct 15, 2013 at 3:45 AM, Benjamin (Inglor) Gruenbaum 
ing...@gmail.com wrote:

 Brendan Eich bren...@mozilla.com wrote:
  We already have good motivation for :: anyway, as sugar for bind. This
 gives relief to the OO side of the expression problem trade-off by allowing
 lexical bindings to be composed with method calls -- beautiful. No third
 scope axis / lookup parameter!

 Yeah, but this doesn't solve the original problem nearly as well IMO since
 it's suddenly different from a normal method call. Having a different call
 operator for scoped extension methods or method invocation seems very
 confusing and counter intuitive for developers.

 If I have to remember different invocation mechanics I kind of lost
 already and I don't have the polymorphism I wanted. I completely agree with
 Allen here.


I don't think that the scoped extensions you want are going to happen. I
used to like the idea of something like that, but I think it will cause a
lot more confusion than its worth. My suggestion for the :: binding
operator was basically just trying to leverage an operator that might be
coming anyway and giving it more purpose. I mean, heck, you know JavaScript
programmers, if :: got added to the language, you *know* people will use it
to make nicer looking (subjectively) APIs in the way I'm describing.

In regards to polymorphism - its not a polymorphic solution out of the box,
or at least - it doesn't provide any affordances for doing polymorphism,
but saying that function calls cannot be polymorphic isn't true, we're
simply flipping around where the polymorphism happens. Yes, I know this
probably sounds like a FP rant, but I think that you can't ignore the FP
side of this (invoking the expression problem again here). OO is good at
adding new cases to the datatype. Functional is good at adding new
functions over the datatype (which is what we're doing here). Trying to get
the best of both worlds likely means playing in the middle. I mean, this
feels like a you got chocolate in my peanut butter you got peanut butter
in may chocolate moment. You say, This operator makes my method calls
unintuitive because its not a dot. Method calls should consistently use
dots. I say, Variables (including function variables) already have well
understood scoping and lookup behavior. The dot operator should have
consistent lookup behavior. Is there a way to marry the functional and OO
to solve this problem?

If we didn't have :: (which we don't now), I think people will continue to
simply use functions like what underscore does. Personally, I'm ok with
that. If I want to have unscoped extensions and live with the consequences
- I will be happy to use symbols. If I want to make a polyfill, I'll just
do it the same way we've been doing it. But, as much as Allen seems to
accuse me of being an FP guy, I still want to have a thing which feels like
a method to be on the right so I find that using :: (if it existed) would
be a nice compromise.

Maybe I'll think about what clojure style protocols would look like to
answer some of the polymorphism questions.

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Allen Wirfs-Brock

On Oct 15, 2013, at 6:40 AM, Mark S. Miller wrote:

 
 
 
 On Tue, Oct 15, 2013 at 3:39 AM, Andreas Rossberg rossb...@google.com wrote:
 On 15 October 2013 03:09, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
  I still don't get why so many JS programmer with a FP orientation want  to 
  do things with the |this| binding.   |this| is for us OO geeks, if you are 
  doing FP you don't need it.
 
 Well, 'this' comes up because you cannot avoid having to interface
 with OOish APIs that conflicts with FPish composition patterns. For
 example, you'd like to be able to do something like
 
   array.map(String.prototype.toLowerCase)
 
I'd be quite comfortable with saying:
  array.map(str=str.toLowerCase())

It preserves the integrity of of the string abstraction rather than just 
assuming that the naked String.prototype.toLowerCase function is the 
appropriate one for any particular str value.

 Using 
 http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
 
 var bind = Function.prototype.bind;
 var uncurryThis = bind.bind(bind.call);
or, in a slightly less obscure formulation that ignores safety):

let uncurryThis = f=((a0, ...args)=f.apply(a0, args))

 
 array.map(uncurryThis(.toLowerCase))
 

although, I still content that  

array.map(str=str.toLowerCase())

is the better formulation. (and fewer characters for those who worry about such 
things)

 
 But map expects a function, while toLowerCase is only available as a
 method. So unless you rewrap all relevant APIs in functional style you
 have to deal with 'this' in one form or the other, and going back and
 forth is not pretty with what JS currently offers. (Mind you, a bind
 operator does not even address this particular example.)
 
 /Andreas
 

I think arrow functions are the appropriate syntactic convenience and since 
this started as a discussion of the :: extension we can assume arrows already 
exist.

We need to know and respect abstraction boundaries. I think careful thought is 
called for each time you cross the FP/OO boundary.  You can't just assume that 
the a function you extracted from a method property is the right function to 
use with other objects.  You can't just assume that the |this| value of a 
method corresponds to the first parameter of a function (or visa vera).

Just because we know how an object is build out of functions, you shouldn't 
routinely take an object abstraction I've created and rip it apart into ins 
more primitive constituent elements  which you then repurpose.  To me, this is 
analogous  to talking a function apart into its machine level code sequences 
and data structures and then doing clever things with them. It's possible, it 
might even be necessary in some very unusual situation, but it should never be 
routine.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Mark S. Miller
On Tue, Oct 15, 2013 at 8:51 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Oct 15, 2013, at 6:40 AM, Mark S. Miller wrote:




 On Tue, Oct 15, 2013 at 3:39 AM, Andreas Rossberg rossb...@google.comwrote:

 On 15 October 2013 03:09, Allen Wirfs-Brock al...@wirfs-brock.com
 wrote:
  I still don't get why so many JS programmer with a FP orientation want
  to do things with the |this| binding.   |this| is for us OO geeks, if you
 are doing FP you don't need it.

 Well, 'this' comes up because you cannot avoid having to interface
 with OOish APIs that conflicts with FPish composition patterns. For
 example, you'd like to be able to do something like

   array.map(String.prototype.toLowerCase)


 I'd be quite comfortable with saying:
   array.map(str=str.toLowerCase())

 It preserves the integrity of of the string abstraction rather than just
 assuming that the naked String.prototype.toLowerCase function is the
 appropriate one for any particular str value.

 Using 
 http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming

 var bind = Function.prototype.bind;
 var uncurryThis = bind.bind(bind.call);

 or, in a slightly less obscure formulation that ignores safety):

 let uncurryThis = f=((a0, ...args)=f.apply(a0, args))


 array.map(uncurryThis(.toLowerCase))


 although, I still content that

 array.map(str=str.toLowerCase())

 is the better formulation. (and fewer characters for those who worry about
 such things)


It depends on what you're trying to express, as you pointed out earlier.
Both address the FP vs OO mismatch -- your's by converting fp to oo,
uncurryThis by converting oo to fp. Regarding Allen's question, I suspect
your's is the better response ;).






 But map expects a function, while toLowerCase is only available as a
 method. So unless you rewrap all relevant APIs in functional style you
 have to deal with 'this' in one form or the other, and going back and
 forth is not pretty with what JS currently offers. (Mind you, a bind
 operator does not even address this particular example.)

 /Andreas


 I think arrow functions are the appropriate syntactic convenience and
 since this started as a discussion of the :: extension we can assume arrows
 already exist.

 We need to know and respect abstraction boundaries. I think careful
 thought is called for each time you cross the FP/OO boundary.  You can't
 just assume that the a function you extracted from a method property is the
 right function to use with other objects.  You can't just assume that the
 |this| value of a method corresponds to the first parameter of a function
 (or visa vera).

 Just because we know how an object is build out of functions, you
 shouldn't routinely take an object abstraction I've created and rip it
 apart into ins more primitive constituent elements  which you then
 repurpose.  To me, this is analogous  to talking a function apart into its
 machine level code sequences and data structures and then doing clever
 things with them. It's possible, it might even be necessary in some very
 unusual situation, but it should never be routine.

 Allen





-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Allen Wirfs-Brock

On Oct 15, 2013, at 7:22 AM, Russell Leggett wrote:

 
 If we didn't have :: (which we don't now), I think people will continue to 
 simply use functions like what underscore does. Personally, I'm ok with that. 
 If I want to have unscoped extensions and live with the consequences - I will 
 be happy to use symbols. If I want to make a polyfill, I'll just do it the 
 same way we've been doing it. But, as much as Allen seems to accuse me of 
 being an FP guy, I still want to have a thing which feels like a method to be 
 on the right so I find that using :: (if it existed) would be a nice 
 compromise.

Hey, it was a general rant and not specifically directed at you or anybody 
else. 

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


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett
On Tue, Oct 15, 2013 at 11:59 AM, Allen Wirfs-Brock
al...@wirfs-brock.comwrote:


 On Oct 15, 2013, at 7:22 AM, Russell Leggett wrote:

 
  If we didn't have :: (which we don't now), I think people will continue
 to simply use functions like what underscore does. Personally, I'm ok with
 that. If I want to have unscoped extensions and live with the consequences
 - I will be happy to use symbols. If I want to make a polyfill, I'll just
 do it the same way we've been doing it. But, as much as Allen seems to
 accuse me of being an FP guy, I still want to have a thing which feels like
 a method to be on the right so I find that using :: (if it existed) would
 be a nice compromise.

 Hey, it was a general rant and not specifically directed at you or anybody
 else.


Sure, no offense taken, I just don't put myself in that camp. Even the use
of |this| I think is justified as not an FP abuse, I just haven't gotten a
chance to flesh out my reasoning yet. Without elaborating too much, (sorry,
no time right now), I basically envision the blend of clojure protocols and
javascript as basically external mixins. Not just a single function, but
potentially a set, and using the |this| for single dispatch the way clojure
protocols use the first arg.

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
First of all interesting analogy and read.

On Tue, Oct 15, 2013 at 5:22 PM, Russell Leggett russell.legg...@gmail.com
 wrote:
 I don't think that the scoped extensions you want are going to happen. I
used to like the idea of something like that, but I think it will cause a
lot more confusion than its worth.

I'm not convinced either. What I'm going to do for the next couple of days
is try to talk to developers about the original _problem_ and see if they
even want to solve it. The confusion vs worth is something I'm trying to
evaluate. Right now it looks like your estimation is correct but I'm not a
fan of partial data.

In a few days when I'll have more concrete data. I'll hopefully be smarter
in this regard then.

 If we didn't have :: (which we don't now), I think people will continue
to simply use functions like what underscore does. Personally, I'm ok with
that

I think using stuff like _.shuffle([1,2,3,4,5]) is not as nice and worse
than [1,2,3,4,5].shuffle() . Especially in a more functional interface that
does not return the original array (we can even have a generator here).


Let's say I have an array [1,2,3,4,5], I want to filter the odd ones,
double the remaining elements and then sum the result. (This is obviously
not a real use case, but I think we both know there are such use cases)

The big issue I see here is chaining.
 `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)`
Is a lot less readable than
 `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))`

The clever `.constructor` trick when extending `Array` solves _that_ use
case but like Brendan said it doesn't address some of the ones in the old
SOE proposal.

Having another invocation syntax like `::` sounds like a __huge__ overhead
to me.


On Tue, Oct 15, 2013 at 5:22 PM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Tue, Oct 15, 2013 at 3:45 AM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com wrote:

 Brendan Eich bren...@mozilla.com wrote:
  We already have good motivation for :: anyway, as sugar for bind. This
 gives relief to the OO side of the expression problem trade-off by allowing
 lexical bindings to be composed with method calls -- beautiful. No third
 scope axis / lookup parameter!

 Yeah, but this doesn't solve the original problem nearly as well IMO
 since it's suddenly different from a normal method call. Having a different
 call operator for scoped extension methods or method invocation seems very
 confusing and counter intuitive for developers.

 If I have to remember different invocation mechanics I kind of lost
 already and I don't have the polymorphism I wanted. I completely agree with
 Allen here.


 I don't think that the scoped extensions you want are going to happen. I
 used to like the idea of something like that, but I think it will cause a
 lot more confusion than its worth. My suggestion for the :: binding
 operator was basically just trying to leverage an operator that might be
 coming anyway and giving it more purpose. I mean, heck, you know JavaScript
 programmers, if :: got added to the language, you *know* people will use it
 to make nicer looking (subjectively) APIs in the way I'm describing.

 In regards to polymorphism - its not a polymorphic solution out of the
 box, or at least - it doesn't provide any affordances for doing
 polymorphism, but saying that function calls cannot be polymorphic isn't
 true, we're simply flipping around where the polymorphism happens. Yes, I
 know this probably sounds like a FP rant, but I think that you can't ignore
 the FP side of this (invoking the expression problem again here). OO is
 good at adding new cases to the datatype. Functional is good at adding new
 functions over the datatype (which is what we're doing here). Trying to get
 the best of both worlds likely means playing in the middle. I mean, this
 feels like a you got chocolate in my peanut butter you got peanut butter
 in may chocolate moment. You say, This operator makes my method calls
 unintuitive because its not a dot. Method calls should consistently use
 dots. I say, Variables (including function variables) already have well
 understood scoping and lookup behavior. The dot operator should have
 consistent lookup behavior. Is there a way to marry the functional and OO
 to solve this problem?

 If we didn't have :: (which we don't now), I think people will continue to
 simply use functions like what underscore does. Personally, I'm ok with
 that. If I want to have unscoped extensions and live with the consequences
 - I will be happy to use symbols. If I want to make a polyfill, I'll just
 do it the same way we've been doing it. But, as much as Allen seems to
 accuse me of being an FP guy, I still want to have a thing which feels like
 a method to be on the right so I find that using :: (if it existed) would
 be a nice compromise.

 Maybe I'll think about what clojure style protocols would look like to
 answer some of the polymorphism questions.

 - Russ


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett


  If we didn't have :: (which we don't now), I think people will continue
 to simply use functions like what underscore does. Personally, I'm ok with
 that

 I think using stuff like _.shuffle([1,2,3,4,5]) is not as nice and worse
 than [1,2,3,4,5].shuffle() . Especially in a more functional interface that
 does not return the original array (we can even have a generator here).


I prefer it too, which is why I suggested :: - its not as nice in terms of
needing to understand a new operator, but it does allow you to think about
it in a more OO way, and it allows for forward chaining without wrappers.




 Let's say I have an array [1,2,3,4,5], I want to filter the odd ones,
 double the remaining elements and then sum the result. (This is obviously
 not a real use case, but I think we both know there are such use cases)

 The big issue I see here is chaining.
  `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)`
 Is a lot less readable than
  `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))`


Speaking of wrappers - underscore does have the chain method which wraps
and allows for chaining. Not ideal, but better, and people are comfortable
with it - I mean look at jQuery.


 Having another invocation syntax like `::` sounds like a __huge__ overhead
 to me.

 Its not an invocation syntax, its fairly trivial binding sugar which can
be used to apply functions to objects as the receiver without modifying the
object, which is precisely what you want to be able to do with SOE even if
you don't like the syntax.

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Brendan Eich

Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
October 15, 2013 12:45 AM
Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote:
 We already have good motivation for :: anyway, as sugar for bind. 
This gives relief to the OO side of the expression problem trade-off 
by allowing lexical bindings to be composed with method calls -- 
beautiful. No third scope axis / lookup parameter!


Yeah, but this doesn't solve the original problem nearly as well IMO 
since it's suddenly different from a normal method call. Having a 
different call operator for scoped extension methods or method 
invocation seems very confusing and counter intuitive for developers.


That's one-sided, though. The other side you are discounting is the 
confusion when code in the scope of the extension wants to call 
cowbow.draw not graphics.draw, but draw has been overridden on the right 
of dot.


Any solution must allow programmers to say what they mean. Since new 
syntax is required even in the dot-based proposal (at the end, to 
declare the extension), the cost of an alternative to dot is not novel 
in the sense of breaking operation on downrev browsers. In other words, 
a compiler to older JS will be required in any event.


If I have to remember different invocation mechanics I kind of lost 
already and I don't have the polymorphism I wanted. I completely agree 
with Allen here.


Which polymorphism to people want? There is a DWIM aspect that cannot 
possibly cover all uses of, e.g., 'draw' on the right of dot.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Allen Wirfs-Brock

On Oct 15, 2013, at 9:44 AM, Benjamin (Inglor) Gruenbaum wrote:

 ...
 
 The big issue I see here is chaining.  
 `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)`   
 Is a lot less readable than
 `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))` 

first let me do a slight rewrite of the above to eliminate some semantic noise:

 import {reduce,map,filter} from underscore2;
reduce(map(filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)
vs 
[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))

Nobody should be thinking of these as equivalent expressions of the same 
computation.  They aren't equivalent because the semantics of the identifiers 
reduce, map, filter are quite different in the two formulation.

They mean different things and when express this way it is pretty clear that 
they are different. I don't see how making them look more similar (while 
maintaining the semantic difference) would help with code clarity.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett


 The big issue I see here is chaining.
  `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)`
 Is a lot less readable than
  `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))`



P.S. This really doesn't look too shabby to me:

import {reduce,map,filter} from underscore2;
[1,2,3,4,5]::filter(x=x%2===0)::map(x=2*x)::reduce((x,y)=x+y))
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Brendan Eich

Allen Wirfs-Brock mailto:al...@wirfs-brock.com
October 14, 2013 6:09 PM

Speaking from the perspective of someone whose probably has permanent 
OO brain damage, it doesn't do a lot for me.


The reason I invoke a method on an object is because I want to do 
polymorphic dispatch on the method name.
myArray::shuffle() doesn't do that for me. No polymorphic dispatch. If 
myArray actually does have a shuffle method it isn't called. If that 
sort of direct function invocation is what I want, I'll just code a 
function call. No method invocation syntax and no |this| value is need.


Not so in the case of Russell's sketched underscore2 (note the 2). 
Underscore (http://underscorejs.org/) provides FP-style APIs hung off a 
_ object, e.g. _.map. Russell's myArray::shuffle() using a shuffle 
imported from underscore2 is clearly using an OO-style API from a 
made-up OO-style underscore2.


I hope this is clear but fear it is not. I know it's not your main point 
-- that there's no fall-forward on Array.prototype.shuffle -- with 
which I agree. But it gets to why |this| matters.


I still don't get why so many JS programmer with a FP orientation want 
to do things with the |this| binding. |this| is for us OO geeks, if 
you are doing FP you don't need it. If you want to write shuffle, 
each, and filter functions just code them as normal functions passing 
the collection as the first argument.


That would be what underscore offers today, perhaps with better exports 
in an ES6 version (import {map, reduce} from underscore-mod, no need 
for _.map, just call map as a function).


If I want to use you functions as a methods on one of my objects I'll 
just code something like:

class {
shuffle() {return shuffle(this)}
}


Why would you both writing such boilerplate if you did not have to?

Assume that the problem of monkeypatching is solved somehow. Then two 
problems remain at play:


P1. How to select an extension in a method (not function) call, in a 
large-ish extent of code where one may want to select a non-extension 
too (on any type of object).


P2. How to fall forward when the extension is not needed because the 
built-in has the method.


Now, what might be useful would be :: that has approximately this 
semantics


import {shuffle,each,filter} from underscore2;
myArray::shuffle();

desugars as

do {let _method = myArray[shuffle.name];
_method ? _method : shuffle}.call(myArray);

in other words, if myArray has a 'shuffle' method, call it; otherwise 
call the default shuffle method that I'm providing.


SOE 
(http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions) 
does this differently, by adding an extension object (associated with a 
prototype object) to a lexical scope, such that in that lexical scope, 
using an object that delegates to the extended prototype will use the 
extension, always. It will not fall forward to prefer a property from 
the object itself.


Quoting from 
http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions#property_lookup_spec_changes:


Section 8.12.1 [[GetOwnProperty]](P) is modified as follows:

When the [[GetOwnProperty]] internal method of O is called with property 
name P and lexical scope L, the following steps are taken:


1.
   Let D be the result of calling [[GetExtensionProperty]] on object O
   with property name P and lexical scope L.
2.
   If D is not undefined, return D.
3.
   Else return [[GetUnextendedOwnProperty]] on object O with property
   name P.

When the [[GetExtensionProperty]] internal method of O is called with 
property name P and lexical scope L, the following steps are taken:


1.
   If O doesn’t have an object extension in lexical scope L return
   undefined.
2.
   Else let E be the object extension for O in lexical scope L.
3.
   Return [[GetUnextendedOwnProperty]] with object E and property name P.


Ok, so maybe this lack of a (P2) solution is just an SOE design choice 
with which you disagree, but we need to be clear. Do we want fallback, 
or fall-forward, or neither? SOE was intended to provide an alternative 
to monkey-patching, with fallback when the named property is accessed on 
an unextended object. This is not the same as fall-forward, AKA object 
detection.


Here I smell more DWIM. People do not mean the same thing when they 
write (just the expression) myArray.shuffle(). The meaning depends, as 
you say, at least on polymorphic dispatch via the prototype chain in JS 
today. We could add more potential kinds of meaning, but TC39ers 
rejected adding a semi-static or dynamic scoped lookup on right of dot, 
per SOE.


What's left in my view is a combination of (a) monkey-patching as we 
know it (object detection is orthogonal and doable), or (b) some new 
operator that enables explicit here is what I mean; do it gesturing, 
or (c) the hypothetical, perhaps infeasible, static-only resolution 
system Andreas posed as a revived SOE requirement.


It so happens that the bind operator -- a solution of the (b) 

Re: Scoped binding of a method to an object

2013-10-15 Thread Brendan Eich

Russell Leggett wrote:



The big issue I see here is chaining.
 `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 ===
0),x=2*x),(x,y)=x+y)`
Is a lot less readable than  
 `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))` 




P.S. This really doesn't look too shabby to me:

import {reduce,map,filter} from underscore2;
[1,2,3,4,5]::filter(x=x%2===0)::map(x=2*x)::reduce((x,y)=x+y))


Right, I think :: beats _. any day :-P.

Seriously, using underscore.js's _. is kind of sandbagging. Allen's 
right, FP-style looks fine but composes inside out rather than via 
chaining (FP'ers like this). No need for this or dot, if you can make 
the world (including built-ins) have this style of API.


Using your proposed underscore2 (OO-underscore?) with :: is no more 
verbose than underscore.js (underscore1), and it has the chaining not 
inside-out-composing win some may prefer.


We should not argue only about taste, and bind (::) has a champion and 
good rationale as an addition to the language.


What I think we should argue about is whether SOE that solves either or 
both problems (P1 and P2) I identified is even possible. Andreas's 
static-only resolution requirement is good. Anyone want to work on that 
angle?


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett
 Using your proposed underscore2 (OO-underscore?) with :: is no more
 verbose than underscore.js (underscore1), and it has the chaining not
 inside-out-composing win some may prefer.


I'm glad you noticed the 2. Perhaps oonderscore? :)



 We should not argue only about taste, and bind (::) has a champion and
 good rationale as an addition to the language.

 What I think we should argue about is whether SOE that solves either or
 both problems (P1 and P2) I identified is even possible. Andreas's
 static-only resolution requirement is good. Anyone want to work on that
 angle?


If we do assume static-only resolution, isn't that trivial to show its
impossible? Wouldn't it require complete type inference? And even then,
what about expressions that evaluate to more than one type?

Btw, another thing I noticed, thinking about using the binding operator
this way, is that it's also a perfect fit for array-likes and array methods.

import {hide} from jQuoory;
let {filter, forEach} = Array.prototype;
document.getElementsByClassName('hello')
::filter(e = e.tagName === span)
::forEach(e = e::hide());

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
Wait, I think maybe I did not understand what you meant before.

Are we talking about using `::` for infixing the first parameter of the
function? As in `func(a,b,c)` being the same as `a::func(b,c)` ?

Would that let us do `[1,2,3,4,5]::_.reduce(x=x%2 ===
0)::_.map(x=2*x)::._.reduce(x,y) = x+y))`? That could actually be pretty
nice, and if that lets us do extension methods that could also be pretty
interesting.

Is this what you meant by `::` and then having extension methods as an
extra syntax?

If not, can you elaborate on `::`? If yes, I'm all ears. This sounds like
an interesting syntactic sugar that could help. It doesn't solve the
problem of putting the method where it belongs but it does solve chaining
quite nicely.




On Tue, Oct 15, 2013 at 7:58 PM, Russell Leggett
russell.legg...@gmail.comwrote:


  If we didn't have :: (which we don't now), I think people will
 continue to simply use functions like what underscore does. Personally, I'm
 ok with that

 I think using stuff like _.shuffle([1,2,3,4,5]) is not as nice and worse
 than [1,2,3,4,5].shuffle() . Especially in a more functional interface that
 does not return the original array (we can even have a generator here).


 I prefer it too, which is why I suggested :: - its not as nice in terms of
 needing to understand a new operator, but it does allow you to think about
 it in a more OO way, and it allows for forward chaining without wrappers.




 Let's say I have an array [1,2,3,4,5], I want to filter the odd ones,
 double the remaining elements and then sum the result. (This is obviously
 not a real use case, but I think we both know there are such use cases)

 The big issue I see here is chaining.
  `_.reduce(_.map(_.filter([1,2,3,4,5],x=x%2 === 0),x=2*x),(x,y)=x+y)`
 Is a lot less readable than
  `[1,2,3,4,5].filter(x=x%2===0).map(x=2*x).reduce((x,y)=x+y))`


 Speaking of wrappers - underscore does have the chain method which wraps
 and allows for chaining. Not ideal, but better, and people are comfortable
 with it - I mean look at jQuery.


 Having another invocation syntax like `::` sounds like a __huge__
 overhead to me.

 Its not an invocation syntax, its fairly trivial binding sugar which can
 be used to apply functions to objects as the receiver without modifying the
 object, which is precisely what you want to be able to do with SOE even if
 you don't like the syntax.

 - Russ

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Russell Leggett
On Tue, Oct 15, 2013 at 4:28 PM, Benjamin (Inglor) Gruenbaum 
ing...@gmail.com wrote:

 Wait, I think maybe I did not understand what you meant before.

 Are we talking about using `::` for infixing the first parameter of the
 function? As in `func(a,b,c)` being the same as `a::func(b,c)` ?


Not exactly. See the proposal
http://wiki.ecmascript.org/doku.php?id=strawman:bind_operator
Essentially, e1::e2 is equivalent to do { let obj=e1; e2.bind(obj) }

Or, in the case of an immediate call, it skips the bind and just does a
Function.prototype.call. In other words,

obj::fun(a,b) is not the same as fun(obj,a,b). Its fun.call(obj,a,b).

The important distinction is that the function being called is expecting a
|this| as opposed to an extra first argument. This is reason I called it
underscore2 - Brendan picked up on that calling it OO underscore.
Functional purists can argue with the approach, but it would let you write
functions exactly as though they were extension methods - using |this|
where appropriate.

The following is a somewhat silly example based on the SOE proposal

module Collections {
  export {
where: Array.prototype.filter,
select: Array.prototype.map
  }
}

module LolCatzDotCom {
  // imports Array.prototype extensions where and select into this
module
  import {where,select} from Collections;

  var allCatz = someArrayValue;
  // Array extensions are in scope
  var cuteCatNames = allCatz::where(cat = cat.isCute)::select(cat =
cat.name);
}

If you still don't get it, give me an example, and I can probably show the
:: equivalent. What is your ideal SOE form? Because my guess is that I can
get it darn close with ::

- Russ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
I think I misunderstood `::` before. if `a::b(x_1,...,x_n)` _just_ means
`b(a,x_1,...,x_n)` I think it might be a good solution to the chaining
problem.

I think the `.constructor` proposal as well as being able to do `::`
completely eliminates the need for extension methods in this regard. It
also behaves similarly to extension methods in C# in that it's _just_ a
static method and it could also introduce interesting options.

I'm not convinced about `::` yet but it seemed to get a lot more positive
feedback from community members I really value and bloggers I talked to
since. The (small) research I'm doing about scoped extension methods or the
problem does not seem to get nearly as good of a response.

The only issue here is:

 Which polymorphism to people want? There is a DWIM aspect that cannot
possibly cover all uses of, e.g., 'draw' on the right of dot.

Let's say I have a classic prototypical inheritance use case.
Cat.prototype.meow = function(){...
Kitten.prototype = new Cat()
Kitten.prototype.purr = function(){ 

Now I have a catOrKitten object. If I define a `function purr(catOrKitten)`
and call `carOrKitten::purr()` , regardless of it being a cat or a kitten -
that function gets called. If I had an extension method on Cat.prototype,
I'd get the correct behavior for kitten who overrides that method on
its prototype.





On Tue, Oct 15, 2013 at 8:26 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 15, 2013 12:45 AM

 Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote:
  We already have good motivation for :: anyway, as sugar for bind. This
 gives relief to the OO side of the expression problem trade-off by allowing
 lexical bindings to be composed with method calls -- beautiful. No third
 scope axis / lookup parameter!

 Yeah, but this doesn't solve the original problem nearly as well IMO
 since it's suddenly different from a normal method call. Having a different
 call operator for scoped extension methods or method invocation seems very
 confusing and counter intuitive for developers.


 That's one-sided, though. The other side you are discounting is the
 confusion when code in the scope of the extension wants to call cowbow.draw
 not graphics.draw, but draw has been overridden on the right of dot.

 Any solution must allow programmers to say what they mean. Since new
 syntax is required even in the dot-based proposal (at the end, to declare
 the extension), the cost of an alternative to dot is not novel in the sense
 of breaking operation on downrev browsers. In other words, a compiler to
 older JS will be required in any event.


  If I have to remember different invocation mechanics I kind of lost
 already and I don't have the polymorphism I wanted. I completely agree with
 Allen here.


 Which polymorphism to people want? There is a DWIM aspect that cannot
 possibly cover all uses of, e.g., 'draw' on the right of dot.

 /be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Dean Landolt
On Mon, Oct 14, 2013 at 8:32 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Oct 14, 2013, at 4:21 PM, Andrea Giammarchi wrote:

  my last memories on the topic are these:
 
  ```javascript
 
  var obj = JSON.parse('{__proto__:[]}');
  obj instanceof Array; // false
  obj.__proto__ instanceof Array; // true
  // since the proto is a property, not a magic thing
  obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^
 
  ```
 
  And since latter should simply set the property named `__proto__` as
 value `123` I got confused with this dual way to deal with an object when
 it comes from JSON world (then has a property defined as value, not the
 inherited set/get from Object.prototype)
 
  As summary, `JSON.parse` over `__proto__` is similar to:
  ```javascript
 
  var o = {};
  Object.defineProperty(o, '__proto__', {
value: 123,
enumerable: true,
writable: true,
configurable: true
  });
 
  ```
 
  Which means in such case the property `__proto__` will fail with such
 object while `Object.setPrototypeOf` won't which is the reason I keep
 suggesting the latest to make the intent explicit.
 
  Not arguing or anything, just speaking out loudly my confusion with that
 property as string part.
 

 I think you are over thinking this:

 Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases
 of interest:

 let o1 = {__proto__: p};  // o1 inherits from p
 let o2 = {__proto__: p};   // o2 inherits from p
 let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own
 data property __proto__ whose value is p.
 let o4 = JSON.parse('{__proto__: value}');
   //o4 inherits from Object.prototype, has own data property
 __proto__ whose value is value

 //assuming that Object.prototype.__proto__ has not been tamper with:
 let o5 = new Object;
 o5.__proto__ = p ; //o5 inherits from p

 let o6 =new Object;
 o6[__proto__] = p; //o6 inherits from p


There seems to be an interesting case missing:

let attr = __proto__;
let o7 = new Object;
o7[attr] = p; // is this like o3?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
Thanks, this clarifies things (the difference between having `this` and a
first argument is really not that big here at all imo and converting
between them two is easy).

  What is your ideal SOE form? Because my guess is that I can get it darn
close with ::

It does seem a lot simpler than actual extension methods with scope
resolution, my only problem with it is the polymorphic case (the equally
silly Cat/Kitten case in my email to Brendan). I'll ask around and have
better conclusions but it does seem to have better feedback from
developers, I think use cases like chaining are good for the wiki page.



On Wed, Oct 16, 2013 at 12:00 AM, Russell Leggett russell.legg...@gmail.com
 wrote:

 On Tue, Oct 15, 2013 at 4:28 PM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com wrote:

 Wait, I think maybe I did not understand what you meant before.

 Are we talking about using `::` for infixing the first parameter of the
 function? As in `func(a,b,c)` being the same as `a::func(b,c)` ?


 Not exactly. See the proposal
 http://wiki.ecmascript.org/doku.php?id=strawman:bind_operator
 Essentially, e1::e2 is equivalent to do { let obj=e1; e2.bind(obj) }

 Or, in the case of an immediate call, it skips the bind and just does a
 Function.prototype.call. In other words,

 obj::fun(a,b) is not the same as fun(obj,a,b). Its fun.call(obj,a,b).

 The important distinction is that the function being called is expecting a
 |this| as opposed to an extra first argument. This is reason I called it
 underscore2 - Brendan picked up on that calling it OO underscore.
 Functional purists can argue with the approach, but it would let you write
 functions exactly as though they were extension methods - using |this|
 where appropriate.

 The following is a somewhat silly example based on the SOE proposal

 module Collections {
   export {
 where: Array.prototype.filter,
 select: Array.prototype.map
   }
 }

 module LolCatzDotCom {
   // imports Array.prototype extensions where and select into this
 module
import {where,select} from Collections;

   var allCatz = someArrayValue;
   // Array extensions are in scope
   var cuteCatNames = allCatz::where(cat = cat.isCute)::select(cat =
 cat.name);
 }

 If you still don't get it, give me an example, and I can probably show the
 :: equivalent. What is your ideal SOE form? Because my guess is that I can
 get it darn close with ::

 - Russ


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
Not resolving this like o3 (or o6 really) sounds very strange. I think:

let attr = __proto__;
let o7 = new Object;
o7[attr] = p; // o7 inherits from p

Is the correct behavior here (why would it not invoke the setter?)



On Wed, Oct 16, 2013 at 12:04 AM, Dean Landolt d...@deanlandolt.com wrote:




 On Mon, Oct 14, 2013 at 8:32 PM, Allen Wirfs-Brock 
 al...@wirfs-brock.comwrote:


 On Oct 14, 2013, at 4:21 PM, Andrea Giammarchi wrote:

  my last memories on the topic are these:
 
  ```javascript
 
  var obj = JSON.parse('{__proto__:[]}');
  obj instanceof Array; // false
  obj.__proto__ instanceof Array; // true
  // since the proto is a property, not a magic thing
  obj.__proto__ = 123; // da hell will happen, only Allen knows ^_^
 
  ```
 
  And since latter should simply set the property named `__proto__` as
 value `123` I got confused with this dual way to deal with an object when
 it comes from JSON world (then has a property defined as value, not the
 inherited set/get from Object.prototype)
 
  As summary, `JSON.parse` over `__proto__` is similar to:
  ```javascript
 
  var o = {};
  Object.defineProperty(o, '__proto__', {
value: 123,
enumerable: true,
writable: true,
configurable: true
  });
 
  ```
 
  Which means in such case the property `__proto__` will fail with such
 object while `Object.setPrototypeOf` won't which is the reason I keep
 suggesting the latest to make the intent explicit.
 
  Not arguing or anything, just speaking out loudly my confusion with
 that property as string part.
 

 I think you are over thinking this:

 Assuming that Annex B.2.2.1 and B.3.1 are implemented: here are the cases
 of interest:

 let o1 = {__proto__: p};  // o1 inherits from p
 let o2 = {__proto__: p};   // o2 inherits from p
 let o3 = {[__proto__]: p};// o3 inherits from Object.prototype, has own
 data property __proto__ whose value is p.
 let o4 = JSON.parse('{__proto__: value}');
   //o4 inherits from Object.prototype, has own data property
 __proto__ whose value is value

 //assuming that Object.prototype.__proto__ has not been tamper with:
 let o5 = new Object;
 o5.__proto__ = p ; //o5 inherits from p

 let o6 =new Object;
 o6[__proto__] = p; //o6 inherits from p


 There seems to be an interesting case missing:

 let attr = __proto__;
 let o7 = new Object;
 o7[attr] = p; // is this like o3?


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Allen Wirfs-Brock

On Oct 15, 2013, at 2:10 PM, Benjamin (Inglor) Gruenbaum wrote:

 Not resolving this like o3 (or o6 really) sounds very strange. I think:
 
 let attr = __proto__;
 let o7 = new Object;
 o7[attr] = p; // o7 inherits from p
 
 Is the correct behavior here (why would it not invoke the setter?)
 
This case is exactly the same as O6.  Perhaps I should have written O6 as:

   o6[ (__proto__) ] = p; //o6 inherits from p

to make that clearer.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Brendan Eich

Benjamin (Inglor) Gruenbaum wrote:

Not resolving this like o3 (or o6 really) sounds very strange. I think:

let attr = __proto__;
let o7 = new Object;
o7[attr] = p; // o7 inherits from p

Is the correct behavior here (why would it not invoke the setter?)


Allen confirmed, but just to be clear, any world where o[foo] and do { 
let key = foo; o[key]; } (do-expression syntax from harmony-era 
strawman) differ is crazytown, and we do not go there.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Brendan Eich

Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
October 15, 2013 2:00 PM
I think I misunderstood `::` before. if `a::b(x_1,...,x_n)` _just_ 
means `b(a,x_1,...,x_n)`


No, rather: `b.call(a, x_1, ..., x_n)` but with the original 
Function.prototype.call (not any shadowing b.call).



I think it might be a good solution to the chaining problem.

I think the `.constructor` proposal as well as being able to do `::` 
completely eliminates the need for extension methods in this regard. 
It also behaves similarly to extension methods in C# in that it's 
_just_ a static method and it could also introduce interesting options.


Indeed static methods with |this| uncurried are easier to call in the 
absence of ::, and this is why I added these so-called static generics 
to SpiderMonkey:


js a = [1,2,3]
[1, 2, 3]
js Array.map(a, x = x*x)
[1, 4, 9]
js Array.reduce(a, (r,x) = r*x)
6
js // etc.

Doing [].map.call(arraylike, mapfun) or worse, 
Array.prototype.map.call(arraylike, mapfun) is just no fun!



The only issue here is:

 Which polymorphism to people want? There is a DWIM aspect that 
cannot possibly cover all uses of, e.g., 'draw' on the right of dot.


Let's say I have a classic prototypical inheritance use case.
Cat.prototype.meow = function(){...
Kitten.prototype = new Cat()
Kitten.prototype.purr = function(){ 

Now I have a catOrKitten object. If I define a `function 
purr(catOrKitten)` and call `carOrKitten::purr()`


This is based on your misunderstanding corrected above -- :: binds the 
object to the left of :: to |this|, not to the first argument.


regardless of it being a cat or a kitten - that function gets called. 
If I had an extension method on Cat.prototype, I'd get the correct 
behavior for kitten who overrides that method on its prototype.


I don't see purr on Cat.prototype --what am I missing?

Anyway, as Russell proposed, :: with imported *methods* (not |this|-free 
functions) is does call the named function, so without multimethods or 
any kind of dispatch based on arguments not receiver (this), you're 
right. You bind a method value to a name and call it on a given |this|.


Allen objected that this doesn't do receiver-based dispatch, which I 
think was your point with the cat and kitten. That's true, and SOE has 
that advantage -- kind of. SOE as I understand the strawman looks in the 
extension object first, and the extension object has no protototype 
object. It's flat. If you use an extension name on some other object 
that is not extended, of course you get polymorphic receiver-based dispatch.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Dean Landolt
On Tue, Oct 15, 2013 at 5:50 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum wrote:

 Not resolving this like o3 (or o6 really) sounds very strange. I think:

 let attr = __proto__;
 let o7 = new Object;
 o7[attr] = p; // o7 inherits from p

 Is the correct behavior here (why would it not invoke the setter?)


 Allen confirmed, but just to be clear, any world where o[foo] and do {
 let key = foo; o[key]; } (do-expression syntax from harmony-era strawman)
 differ is crazytown, and we do not go there.


True, but the __proto__ train left the station bound for crazytown long
ago...

So just to be clear, the only way to add a __proto__ property to an
existing object is with Object.defineProperty?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Allen Wirfs-Brock

On Oct 15, 2013, at 3:19 PM, Dean Landolt wrote:

 
 So just to be clear, the only way to add a __proto__ property to an existing 
 object is with Object.defineProperty?
 


Object.mixin(obj, {[__proto__]:42});

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


Re: Readdition of __proto__

2013-10-15 Thread Andrea Giammarchi
not if you parsed that object via `JSON.parse('{__proto__:[]}')`

in this case is the equivalent of that operation through
`Object.defineProperty({}, '__proto__', {enumerable: true, writable: true,
configurable: true})` so that `obj.__proto__` will result into property
assignment and no setter invoked.

```javascript
var o = JSON.parse('{__proto__:[]}');

o.__proto__ = Date.prototype;

o instanceof Date;// false
o.getTime === void 0; // true

delete o.__proto__;   // true

// once again
o.__proto__ = Date.prototype;

// but this time ...
o instanceof Date;// true
o.getTime;// function[native]
```

Cheers


On Tue, Oct 15, 2013 at 3:19 PM, Dean Landolt d...@deanlandolt.com wrote:




 On Tue, Oct 15, 2013 at 5:50 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum wrote:

 Not resolving this like o3 (or o6 really) sounds very strange. I think:

 let attr = __proto__;
 let o7 = new Object;
 o7[attr] = p; // o7 inherits from p

 Is the correct behavior here (why would it not invoke the setter?)


 Allen confirmed, but just to be clear, any world where o[foo] and do {
 let key = foo; o[key]; } (do-expression syntax from harmony-era strawman)
 differ is crazytown, and we do not go there.


 True, but the __proto__ train left the station bound for crazytown long
 ago...

 So just to be clear, the only way to add a __proto__ property to an
 existing object is with Object.defineProperty?


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Readdition of __proto__

2013-10-15 Thread Andrea Giammarchi
oh, that's cute :D

too bad I cannot shim/polyfill that in my `Object.mixin` module.

I would simply *red-flag* it and discourage the usage of `__proto__`
everywhere is possible (uhm wait ... I've already done that in the past,
never mind ... )

Happy `__dunder__` Everybody,
  Cheers




On Tue, Oct 15, 2013 at 4:03 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Oct 15, 2013, at 3:19 PM, Dean Landolt wrote:

 
  So just to be clear, the only way to add a __proto__ property to an
 existing object is with Object.defineProperty?
 


 Object.mixin(obj, {[__proto__]:42});

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


Re: Scoped binding of a method to an object

2013-10-15 Thread Andrea Giammarchi
wait ... what ?


On Tue, Oct 15, 2013 at 2:00 PM, Russell Leggett
russell.legg...@gmail.comwrote:


 obj::fun(a,b) is not the same as fun(obj,a,b). Its fun.call(obj,a,b).



isn't this basically the equivalent of obj-fun then ? (yes, the other
arrow that was an arrow too far)

Thanks for clarification
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Andrea Giammarchi
uhm, never mind, I got it now. Borrowing functions avoiding call/apply
looks good.

Best Regards


On Tue, Oct 15, 2013 at 4:17 PM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 wait ... what ?


 On Tue, Oct 15, 2013 at 2:00 PM, Russell Leggett 
 russell.legg...@gmail.com wrote:


 obj::fun(a,b) is not the same as fun(obj,a,b). Its fun.call(obj,a,b).



 isn't this basically the equivalent of obj-fun then ? (yes, the other
 arrow that was an arrow too far)

 Thanks for clarification


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Scoped binding of a method to an object

2013-10-15 Thread Benjamin (Inglor) Gruenbaum
On Wed, Oct 16, 2013 at 1:04 AM, Brendan Eich bren...@mozilla.com wrote:
 No, rather: `b.call(a, x_1, ..., x_n)` but with the original
Function.prototype.call (not any shadowing b.call).

Right, Russell clarified `::` to me and sent a link to the wiki (always
good!). Thanks.

 I don't see purr on Cat.prototype --what am I missing?

You're missing nothing. Cat doesn't have a `purr` on the prototype but
Kitten whose prototype is a cat does.

By adding a scoped extension to Cat.protoype to the current module and then
calling `myObj.purr` I'd expect:

 - If myObj is a Cat, the scoped extension will be called
 - If myObj is also a Kitten, Kitten.prototype.purr will be called instead
since Kitten.prototype is sooner in the prototype chain.

This enables a sort of polymorphism in my opininion - whether it's very
useful or not is another question but it's something the `::`  bind syntax
doesn't really solve.

 Allen objected that this doesn't do receiver-based dispatch, which I
think was your point with the cat and kitten. That's true,

Yes, that's the issue - but I'm no longer as convinced that the use case is
strong enough to justify a whole new language construct.





On Wed, Oct 16, 2013 at 1:04 AM, Brendan Eich bren...@mozilla.com wrote:

  Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 15, 2013 2:00 PM

 I think I misunderstood `::` before. if `a::b(x_1,...,x_n)` _just_ means
 `b(a,x_1,...,x_n)`


 No, rather: `b.call(a, x_1, ..., x_n)` but with the original
 Function.prototype.call (not any shadowing b.call).


  I think it might be a good solution to the chaining problem.

 I think the `.constructor` proposal as well as being able to do `::`
 completely eliminates the need for extension methods in this regard. It
 also behaves similarly to extension methods in C# in that it's _just_ a
 static method and it could also introduce interesting options.


 Indeed static methods with |this| uncurried are easier to call in the
 absence of ::, and this is why I added these so-called static generics to
 SpiderMonkey:

 js a = [1,2,3]
 [1, 2, 3]
 js Array.map(a, x = x*x)
 [1, 4, 9]
 js Array.reduce(a, (r,x) = r*x)
 6
 js // etc.

 Doing [].map.call(arraylike, mapfun) or worse, 
 Array.prototype.map.call(**arraylike,
 mapfun) is just no fun!


  The only issue here is:

  Which polymorphism to people want? There is a DWIM aspect that cannot
 possibly cover all uses of, e.g., 'draw' on the right of dot.

 Let's say I have a classic prototypical inheritance use case.
 Cat.prototype.meow = function(){...
 Kitten.prototype = new Cat()
 Kitten.prototype.purr = function(){ 

 Now I have a catOrKitten object. If I define a `function
 purr(catOrKitten)` and call `carOrKitten::purr()`


 This is based on your misunderstanding corrected above -- :: binds the
 object to the left of :: to |this|, not to the first argument.


  regardless of it being a cat or a kitten - that function gets called. If
 I had an extension method on Cat.prototype, I'd get the correct
 behavior for kitten who overrides that method on its prototype.


 I don't see purr on Cat.prototype --what am I missing?

 Anyway, as Russell proposed, :: with imported *methods* (not |this|-free
 functions) is does call the named function, so without multimethods or any
 kind of dispatch based on arguments not receiver (this), you're right. You
 bind a method value to a name and call it on a given |this|.

 Allen objected that this doesn't do receiver-based dispatch, which I think
 was your point with the cat and kitten. That's true, and SOE has that
 advantage -- kind of. SOE as I understand the strawman looks in the
 extension object first, and the extension object has no protototype object.
 It's flat. If you use an extension name on some other object that is not
 extended, of course you get polymorphic receiver-based dispatch.

 /be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss