Scoped binding of a method to an object

2013-10-13 Thread Benjamin (Inglor) Gruenbaum
Scoped binding of a method to an object

Well, I know how some languages solve this issue but I wondered if
ECMAScript considered addressing this or already have and I missed it.

Often, I want to extend objects, for example -

Array.prototype.shuffle - takes an array and shuffles it.

However, this is considered bad practice for many reasons I don't have to
repeat here (what if other libraries also override it? What if some user
code? What if it makes it to the standard some day?)

The problem is even more prevalent in stuff like String.prototype.contains
which we know will be in the next spec - people had little way to add that
function to the string prototype *before* it was adapted to the spec and
not get eventually bitten.

Stuff like underscore _.shuffle makes for less object oriented code, I find
it harder to write and it feels like the code is not where it belongs.

What I'd like is a way to add such methods in a scoped way, so within *my* code
I get to use .shuffle but any code that is not in that scoped block does
not get access to this method.

Has there been a proposal or discussion about this in the past?

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


Re: Generic Bundling

2013-10-13 Thread Andrea Giammarchi
On Sat, Oct 12, 2013 at 12:07 PM, Brendan Eich bren...@mozilla.com wrote:


 However, Russell's counter-argument that fallback in older browsers to
 loading lots of little files, request by request, from the server directory
 hierarchy, may be too painful, reducing the value as a migration technique.


this is what happens today with external CDN scripts and/or AMD like
solutions regardless ... if these are not bundled all together, isn't it?


Is there a way for old browsers that avoids a request storm, and which can
 be expressed entirely in the hosted content (no protocol stack update
 problem)?


hacking HTML SCRIPT prototype upfront, it's possible to improve the
behavior but hard to make it fully able to ignore network requests.

However, this is not usually the main concern for new/recent proposals so I
wonder why it is in such specific case?

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


Re: Generic Bundling

2013-10-13 Thread Brian Kardell
On Oct 13, 2013 4:40 AM, Andrea Giammarchi andrea.giammar...@gmail.com
wrote:


 On Sat, Oct 12, 2013 at 12:07 PM, Brendan Eich bren...@mozilla.com
wrote:


 However, Russell's counter-argument that fallback in older browsers to
loading lots of little files, request by request, from the server directory
hierarchy, may be too painful, reducing the value as a migration technique.


 this is what happens today with external CDN scripts and/or AMD like
solutions regardless ... if these are not bundled all together, isn't it?

To me at least, the primary difference there is that in that case it is in
the authors hand whereas native feature support is in the hands of the user
agent, creating a potentially huge and unmanageable perf delta in the
short/medium term.
___
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-13 Thread Rick Waldron
On Sun, Oct 13, 2013 at 3:54 AM, Benjamin (Inglor) Gruenbaum 
ing...@gmail.com wrote:

 Scoped binding of a method to an object

 Well, I know how some languages solve this issue but I wondered if
 ECMAScript considered addressing this or already have and I missed it.

 Often, I want to extend objects, for example -

 Array.prototype.shuffle - takes an array and shuffles it.

 However, this is considered bad practice for many reasons I don't have to
 repeat here (what if other libraries also override it? What if some user
 code? What if it makes it to the standard some day?)

 The problem is even more prevalent in stuff like String.prototype.contains
 which we know will be in the next spec - people had little way to add that
 function to the string prototype *before* it was adapted to the spec and
 not get eventually bitten.

 Stuff like underscore _.shuffle makes for less object oriented code, I
 find it harder to write and it feels like the code is not where it belongs.

 What I'd like is a way to add such methods in a scoped way, so within *my* 
 code
 I get to use .shuffle but any code that is not in that scoped block does
 not get access to this method.

 Has there been a proposal or discussion about this in the past?


This is trivial with Symbols:

  let shuffle = Symbol();

  Array.prototype[shuffle] = function() {...};


Only code that has access to the `shuffle` symbol may use the method:

  let shuffled = array[shuffle]();


Rick
___
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-13 Thread Kevin Smith


 This is trivial with Symbols:

   let shuffle = Symbol();

   Array.prototype[shuffle] = function() {...};


 Only code that has access to the `shuffle` symbol may use the method:

   let shuffled = array[shuffle]();


Unfortunately, such a construction will fail in a multi-realm (i.e.
multiple frames) environment.

{ Kevin }
___
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-13 Thread Till Schneidereit
On Sun, Oct 13, 2013 at 6:45 PM, Kevin Smith zenpars...@gmail.com wrote:

 This is trivial with Symbols:

   let shuffle = Symbol();

   Array.prototype[shuffle] = function() {...};


 Only code that has access to the `shuffle` symbol may use the method:

   let shuffled = array[shuffle]();


 Unfortunately, such a construction will fail in a multi-realm (i.e. multiple
 frames) environment.

That's what the symbol registry will solve, though.
___
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-13 Thread Brendan Eich

Apologies for the (iPad + haste)-induced typos below :-(.

/be


Brendan Eich mailto:bren...@mozilla.com
October 13, 2013 10:17 AM
Benjamin (Inglor) Gruenbaum wrote:
However, this is considered bad practice for many reasons I don't 
have to repeat here (what if other libraries also override it? What 
if some user code? What if it makes it to the standard some day?)


Actually, people say extending Object.prototype is bad practive 
(verboten, the original post, IIRC from Arv, said; yes, I recalled 
correctly: http://erik.eae.net/archives/2005/06/06/22.13.54/).


Extending Array.prototype is less so, and PrototypeJS did it. Other 
libraries extend built-in prototypes. Some even take care not to jump 
a prior claim.


The problem is even more prevalent in stuff like 
String.prototype.contains which we know will be in the next spec - 
people had little way to add that function to the string prototype 
/before/ it was adapted to the spec and not get eventually bitten.


No, object detection, polyfilling, and even prollyfilling are common 
and successful adaptationsp on the Web.


Symbols help but (without dot syntax) also hurt. We'll see how much 
use they get in the future, but for the record, string-equated names 
have been and will be used to extend standard built-ins too.


Your subject recalls a defunct proposal to add lexically-scoped but 
heap-based -- therefore object property-lookup performance hindering 
-- extension properties. This proposal died precise because of the 
performance problem.


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

Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
October 13, 2013 12:54 AM
Scoped binding of a method to an object

Well, I know how some languages solve this issue but I wondered if 
ECMAScript considered addressing this or already have and I missed it.


Often, I want to extend objects, for example -

Array.prototype.shuffle - takes an array and shuffles it.

However, this is considered bad practice for many reasons I don't have 
to repeat here (what if other libraries also override it? What if some 
user code? What if it makes it to the standard some day?)


The problem is even more prevalent in stuff like 
String.prototype.contains which we know will be in the next spec - 
people had little way to add that function to the string prototype 
/before/ it was adapted to the spec and not get eventually bitten.


Stuff like underscore _.shuffle makes for less object oriented code, I 
find it harder to write and it feels like the code is not where it 
belongs.


What I'd like is a way to add such methods in a scoped way, so within 
/my/ code I get to use .shuffle but any code that is not in that 
scoped block does not get access to this method.


Has there been a proposal or discussion about this in the past?

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

___
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-13 Thread Erik Arvidsson
We did proposes this back in 2011

http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions

I wasn't at this actual F2F meeting so I don't know many details.
Brendan might remember what the blocking issue was?

On Sun, Oct 13, 2013 at 1:19 PM, Brendan Eich bren...@mozilla.com wrote:
 Apologies for the (iPad + haste)-induced typos below :-(.

 /be

 Brendan Eich mailto:bren...@mozilla.com
 October 13, 2013 10:17 AM

 Benjamin (Inglor) Gruenbaum wrote:

 However, this is considered bad practice for many reasons I don't have to
 repeat here (what if other libraries also override it? What if some user
 code? What if it makes it to the standard some day?)


 Actually, people say extending Object.prototype is bad practive (verboten,
 the original post, IIRC from Arv, said; yes, I recalled correctly:
 http://erik.eae.net/archives/2005/06/06/22.13.54/).

 Extending Array.prototype is less so, and PrototypeJS did it. Other
 libraries extend built-in prototypes. Some even take care not to jump a
 prior claim.

 The problem is even more prevalent in stuff like
 String.prototype.contains which we know will be in the next spec - people
 had little way to add that function to the string prototype /before/ it was
 adapted to the spec and not get eventually bitten.


 No, object detection, polyfilling, and even prollyfilling are common and
 successful adaptationsp on the Web.

 Symbols help but (without dot syntax) also hurt. We'll see how much use
 they get in the future, but for the record, string-equated names have been
 and will be used to extend standard built-ins too.

 Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension properties. This proposal died precise because of the performance
 problem.

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

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

 Scoped binding of a method to an object

 Well, I know how some languages solve this issue but I wondered if
 ECMAScript considered addressing this or already have and I missed it.

 Often, I want to extend objects, for example -

 Array.prototype.shuffle - takes an array and shuffles it.

 However, this is considered bad practice for many reasons I don't have to
 repeat here (what if other libraries also override it? What if some user
 code? What if it makes it to the standard some day?)

 The problem is even more prevalent in stuff like String.prototype.contains
 which we know will be in the next spec - people had little way to add that
 function to the string prototype /before/ it was adapted to the spec and not
 get eventually bitten.

 Stuff like underscore _.shuffle makes for less object oriented code, I
 find it harder to write and it feels like the code is not where it belongs.

 What I'd like is a way to add such methods in a scoped way, so within /my/
 code I get to use .shuffle but any code that is not in that scoped block
 does not get access to this method.


 Has there been a proposal or discussion about this in the past?

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

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



-- 
erik
___
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-13 Thread Till Schneidereit
On Sun, Oct 13, 2013 at 7:17 PM, Brendan Eich bren...@mozilla.com wrote:
 Benjamin (Inglor) Gruenbaum wrote:

 However, this is considered bad practice for many reasons I don't have to
 repeat here (what if other libraries also override it? What if some user
 code? What if it makes it to the standard some day?)


 Actually, people say extending Object.prototype is bad practive (verboten,
 the original post, IIRC from Arv, said; yes, I recalled correctly:
 http://erik.eae.net/archives/2005/06/06/22.13.54/).

 Extending Array.prototype is less so, and PrototypeJS did it. Other
 libraries extend built-in prototypes. Some even take care not to jump a
 prior claim.

Given the hoops we have to jump through because of Array.prototype and
String#prototype extensions right now ([1] and Unscopable), I would
argue that extending any builtins' prototypes without at least some
poor-man's namespacing shouldn't be done, either.

I do agree that poly- and prollyfilling can be quite convenient, but
ISTM that the problems they create for the language's builtins library
ability to evolve only increase over time.

If we ever manage to introduce better syntax for by-symbol property
lookups, that problem would be thoroughly solved.

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=903755

 The problem is even more prevalent in stuff like String.prototype.contains
 which we know will be in the next spec - people had little way to add that
 function to the string prototype /before/ it was adapted to the spec and not
 get eventually bitten.


 No, object detection, polyfilling, and even prollyfilling are common and
 successful adaptationsp on the Web.

 Symbols help but (without dot syntax) also hurt. We'll see how much use they
 get in the future, but for the record, string-equated names have been and
 will be used to extend standard built-ins too.

 Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension properties. This proposal died precise because of the performance
 problem.

 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
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-13 Thread Benjamin (Inglor) Gruenbaum
David Bruant bruan...@gmail.com wrote
 This proposal does not aim at solving the problem of library conflicts
which existed before this proposal and should be solve independently.

Of course, and I'm sorry if I implied otherwise. I'm sure we all
acknowledge the problem of extending the native prototypes in libraries. I
just don't understand how having a `_` prefix attempts to give us a
solution to the problem. I'm not saying I have a solution either, but I
think implying that it's ok to extend them with a prefix doesn't really
solve much. Maybe I got what you were trying to say wrong though.




On Sun, Oct 13, 2013 at 9:25 PM, David Bruant bruan...@gmail.com wrote:

  Le 13/10/2013 20:03, Benjamin (Inglor) Gruenbaum a écrit :

  David Bruant bruan...@gmail.com wrote:
   Concretely, attempted prolyfills, could be _-prefixed (that really
 fits with what you call poor-man's prefixing, I believe)
   Authors would feel free to add something like Array.prototype._shuffle
 or Array.prototype._last, or EventTarget.prototype._on without worrying
 about collision with the platform.

  What if I use two libraries that polyfill `_shuffle` or `_last`
 differently (let's say with different behavior for an empty array for
 `_last` or weaker guarantee on the randomness in `_shuffle`)?

 What do you do today when a library overrides Array.prototype.concat with
 a different semantics?
 What do you do when you load two libraries each defining a global $ with
 different semantics?

 Apply every prevention/resolution mechanism you use today with global
 properties. Among other ideas:
 * don't load libraries that are known to have conflicts (!!)
 * isolate the code that enhance built-ins (preferably, run it before
 anything else and not in the middle of your application lifecycle)
 * Define functions as non-configurable/non-writable in development mode to
 discover conflicts before pushing to production.

 This proposal does not aim at solving the problem of library conflicts
 which existed before this proposal and should be solve independently.

 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-13 Thread Mark S. Miller
Any library that monkey patches primordials and wishes to be able to rely
on the primordials being mutated only according to it should demand to be
run before primordials are otherwise corrupted or frozen, and should freeze
the primordials after patching. Of course, such a library isn't a library
in the traditional sense -- it is a kernel for everything loaded into that
realm after it. Two such kernels aren't composable because of this
unsolvable conflict problem.

Libraries meant to be composable should not mutate primordials, and should
assume only that primordials are in some uncorrupted state.



On Sun, Oct 13, 2013 at 11:25 AM, David Bruant bruan...@gmail.com wrote:

  Le 13/10/2013 20:03, Benjamin (Inglor) Gruenbaum a écrit :

  David Bruant bruan...@gmail.com wrote:
   Concretely, attempted prolyfills, could be _-prefixed (that really
 fits with what you call poor-man's prefixing, I believe)
   Authors would feel free to add something like Array.prototype._shuffle
 or Array.prototype._last, or EventTarget.prototype._on without worrying
 about collision with the platform.

  What if I use two libraries that polyfill `_shuffle` or `_last`
 differently (let's say with different behavior for an empty array for
 `_last` or weaker guarantee on the randomness in `_shuffle`)?

 What do you do today when a library overrides Array.prototype.concat with
 a different semantics?
 What do you do when you load two libraries each defining a global $ with
 different semantics?

 Apply every prevention/resolution mechanism you use today with global
 properties. Among other ideas:
 * don't load libraries that are known to have conflicts (!!)
 * isolate the code that enhance built-ins (preferably, run it before
 anything else and not in the middle of your application lifecycle)
 * Define functions as non-configurable/non-writable in development mode to
 discover conflicts before pushing to production.

 This proposal does not aim at solving the problem of library conflicts
 which existed before this proposal and should be solve independently.

 David

 ___
 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-13 Thread David Bruant

Le 13/10/2013 20:29, Benjamin (Inglor) Gruenbaum a écrit :

David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote
 This proposal does not aim at solving the problem of library 
conflicts which existed before this proposal and should be solve 
independently.


Of course, and I'm sorry if I implied otherwise. I'm sure we all 
acknowledge the problem of extending the native prototypes in 
libraries. I just don't understand how having a `_` prefix attempts to 
give us a solution to the problem. I'm not saying I have a solution 
either, but I think implying that it's ok to extend them with a prefix 
doesn't really solve much. Maybe I got what you were trying to say 
wrong though.

Not wrong, but partial ;-)
'_'-prefixing isn't a solution in itself. It requires a commitment from 
the platform to say they won't make use of this namespace in the future, 
thus allowing authors to use this namespace without worrying about 
future conflicts.


Just to clarify a point, I started speaking about _-prefixing after 
Till's point about the language's builtins library ability to evolve. 
My point is somewhat unrelated to scoped binding and is not a solution 
for that (I should fork the thread if we continue discussing this).


David






On Sun, Oct 13, 2013 at 9:25 PM, David Bruant bruan...@gmail.com 
mailto:bruan...@gmail.com wrote:


Le 13/10/2013 20:03, Benjamin (Inglor) Gruenbaum a écrit :

David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote:

 Concretely, attempted prolyfills, could be _-prefixed (that
really fits with what you call poor-man's prefixing, I believe)
 Authors would feel free to add something like
Array.prototype._shuffle or Array.prototype._last, or
EventTarget.prototype._on without worrying about collision with
the platform.

What if I use two libraries that polyfill `_shuffle` or `_last`
differently (let's say with different behavior for an empty array
for `_last` or weaker guarantee on the randomness in `_shuffle`)?

What do you do today when a library overrides
Array.prototype.concat with a different semantics?
What do you do when you load two libraries each defining a global
$ with different semantics?

Apply every prevention/resolution mechanism you use today with
global properties. Among other ideas:
* don't load libraries that are known to have conflicts (!!)
* isolate the code that enhance built-ins (preferably, run it
before anything else and not in the middle of your application
lifecycle)
* Define functions as non-configurable/non-writable in development
mode to discover conflicts before pushing to production.

This proposal does not aim at solving the problem of library
conflicts which existed before this proposal and should be solve
independently.

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-13 Thread Benjamin (Inglor) Gruenbaum
 Prollyfilling is great too (perhaps you disagree?), and as its name
suggests it happens *before* the method is added to the spec.

So in your opinion adding a `.shuffle` method to an Array in a library I
ship to users is a good idea if it makes my code clearer and nicer?

I'm not saying I disagree, I'm not one of those people who passes an extra
parameter for `undefined` in a function. I just think it can be very risky.

When I have to work on big code bases that run JavaScript end to end using
multiple frameworks and libraries on both sides, I find that extending
object prototypes can be _very_ risky - and Prollyfilling (nice term by
the way) has bitten me before. Sure, in _my_ code it can be very nice, but
I expect libraries to have little to no side effects on my code and that's
exactly the cases it can bite me.

 How exactly did that example fail? The differences in detail hardly
matter; PrototypeJS trod a cow-path that ES5 paved. Most users don't worry
about the edge case differences.

I don't think anyone today is doubting the enormous contribution
PrototypeJS had and `.bind` was very useful in it and is very useful in
ES5. However, running into edge cases and getting unexpected results is
something I don't think people appreciate. The SweetJS case is just as
interesting.

There is no doubt some of the most interesting API additions have come from
people extending natives and that says something. However, today when
rather than writing 1000 line pages I see more and more 100 thousand lines
code bases using multiple libraries - side effects that extending natives
sound _very_ scary, and being able to extend the natives in a way that does
not bite me is something I'd _really_ love to play with.

 Don't worry about syntax yet.

Of course, I was just toying around. Like I've said before, pretty much
anyone else in this discussion is more qualified to come with an actual
solution than me.

 This must cost, and it does cost.

Would you mind elaborating on that or linking to relevant discussion about
the last proposal? I'd love to understand the issues involved and get a
better understanding of the challenges something like this would bring.




On Sun, Oct 13, 2013 at 9:37 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 13, 2013 11:00 AM

 Brendan Eichbren...@mozilla.com mailto:bren...@mozilla.com wrote:
  No, object detection, polyfilling, and even prollyfilling are common
 and successful adaptationsp on the Web.

 Polyfilling is great _after_ the method has already been added to the
 spec.


 Prollyfilling is great too (perhaps you disagree?), and as its name
 suggests it happens *before* the method is added to the spec.


  I'm completely fine with adding an Array.prototype.map shim to IE8, the
 problem with adding a method that's not on the prototype yet is that it'll
 fail in case the spec is different from the implementation I chose. If you
 mentioned PrototypeJS, its `.bind` method is one such example.


 How exactly did that example fail? The differences in detail hardly
 matter; PrototypeJS trod a cow-path that ES5 paved. Most users don't worry
 about the edge case differences.


   Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension properties.

 I have to say this surprises me, a performance issue is the last thing I
 expected. What about attaching a prototype as a closure variable, something
 (and this is a syntax I __don't__ like) like:
 ```
 (function(use Array){
 Array.prototype.contains = function() { ...
 ...
 // any code here has access to .contains, code that did not originate
 here does not have such access, much like a closure.
 // other code is free to use Array without any collisions.
 })()
 ```
 Again, I __don't__ like this sort of syntax and I'm __not__ sure about
 the semantics here, I just noticed I have this problem - I'm probably not
 the most qualified for coming up with the solution out of the amazing minds
 right here.

  Don't worry about syntax yet. The issue in any such semantic extension
 is the required extra lookup parameter: not just contains on the right of
 dot, but the enclosing closure scope.

 Unqualified identifiers (ones not used after dot) indeed require lookup
 via closure environments, to the global (let's ignore 'with' and DOM inline
 event handlers).

 Dot-qualified identifiers and equivalent bracketed computed property name
 accesses require prototype chain lookup.

 No matter the syntax, and independent of details of how one specs it,
 you're proposing a hybrid of the two schemes. This must cost, and it does
 cost.

 /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-13 Thread Mark S. Miller
On Sun, Oct 13, 2013 at 11:36 AM, Benjamin (Inglor) Gruenbaum 
ing...@gmail.com wrote:

 First of all - well put.


Thanks.



 Second, wouldn't being able to do this in a scoped way solve the conflict
 problem?


As Brendan points out, doing this in a scoped way adds a third parameter
representing the scope, or that somehow needs to be scope specific. Such a
third parameter needs to be first class. WeakMaps and relationships do
exactly that.





 On Sun, Oct 13, 2013 at 9:33 PM, Mark S. Miller erig...@google.comwrote:

 Any library that monkey patches primordials and wishes to be able to rely
 on the primordials being mutated only according to it should demand to be
 run before primordials are otherwise corrupted or frozen, and should freeze
 the primordials after patching. Of course, such a library isn't a library
 in the traditional sense -- it is a kernel for everything loaded into that
 realm after it. Two such kernels aren't composable because of this
 unsolvable conflict problem.

 Libraries meant to be composable should not mutate primordials, and
 should assume only that primordials are in some uncorrupted state.



  On Sun, Oct 13, 2013 at 11:25 AM, David Bruant bruan...@gmail.comwrote:

  Le 13/10/2013 20:03, Benjamin (Inglor) Gruenbaum a écrit :

  David Bruant bruan...@gmail.com wrote:
   Concretely, attempted prolyfills, could be _-prefixed (that
 really fits with what you call poor-man's prefixing, I believe)
   Authors would feel free to add something like
 Array.prototype._shuffle or Array.prototype._last, or
 EventTarget.prototype._on without worrying about collision with the
 platform.

  What if I use two libraries that polyfill `_shuffle` or `_last`
 differently (let's say with different behavior for an empty array for
 `_last` or weaker guarantee on the randomness in `_shuffle`)?

 What do you do today when a library overrides Array.prototype.concat
 with a different semantics?
 What do you do when you load two libraries each defining a global $ with
 different semantics?

 Apply every prevention/resolution mechanism you use today with global
 properties. Among other ideas:
 * don't load libraries that are known to have conflicts (!!)
 * isolate the code that enhance built-ins (preferably, run it before
 anything else and not in the middle of your application lifecycle)
 * Define functions as non-configurable/non-writable in development mode
 to discover conflicts before pushing to production.

 This proposal does not aim at solving the problem of library conflicts
 which existed before this proposal and should be solve independently.

 David

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




 --
 Cheers,
 --MarkM





-- 
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-13 Thread Benjamin (Inglor) Gruenbaum
As Brendan points out, doing this in a scoped way adds a third parameter
representing the scope, or that somehow needs to be scope specific. Such a
third parameter needs to be first class. WeakMaps and relationships do
exactly that.

My relative lack of experience here is probably working against me.

Would you mind explaining how WeakMaps (and later relationships) give me
that third scope parameter? Also, are you implying adding this sort of
scoped extension of a native prototype be possible/easy once those features
are implemented?

(Sending me to reading is great too, I don't want to waste your time)


On Sun, Oct 13, 2013 at 10:00 PM, Mark S. Miller erig...@google.com wrote:

 On Sun, Oct 13, 2013 at 11:36 AM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com wrote:

 First of all - well put.


 Thanks.



 Second, wouldn't being able to do this in a scoped way solve the conflict
 problem?


 As Brendan points out, doing this in a scoped way adds a third parameter
 representing the scope, or that somehow needs to be scope specific. Such a
 third parameter needs to be first class. WeakMaps and relationships do
 exactly that.





 On Sun, Oct 13, 2013 at 9:33 PM, Mark S. Miller erig...@google.comwrote:

 Any library that monkey patches primordials and wishes to be able to
 rely on the primordials being mutated only according to it should demand to
 be run before primordials are otherwise corrupted or frozen, and should
 freeze the primordials after patching. Of course, such a library isn't a
 library in the traditional sense -- it is a kernel for everything loaded
 into that realm after it. Two such kernels aren't composable because of
 this unsolvable conflict problem.

 Libraries meant to be composable should not mutate primordials, and
 should assume only that primordials are in some uncorrupted state.



  On Sun, Oct 13, 2013 at 11:25 AM, David Bruant bruan...@gmail.comwrote:

  Le 13/10/2013 20:03, Benjamin (Inglor) Gruenbaum a écrit :

  David Bruant bruan...@gmail.com wrote:
   Concretely, attempted prolyfills, could be _-prefixed (that
 really fits with what you call poor-man's prefixing, I believe)
   Authors would feel free to add something like
 Array.prototype._shuffle or Array.prototype._last, or
 EventTarget.prototype._on without worrying about collision with the
 platform.

  What if I use two libraries that polyfill `_shuffle` or `_last`
 differently (let's say with different behavior for an empty array for
 `_last` or weaker guarantee on the randomness in `_shuffle`)?

 What do you do today when a library overrides Array.prototype.concat
 with a different semantics?
 What do you do when you load two libraries each defining a global $
 with different semantics?

 Apply every prevention/resolution mechanism you use today with global
 properties. Among other ideas:
 * don't load libraries that are known to have conflicts (!!)
 * isolate the code that enhance built-ins (preferably, run it before
 anything else and not in the middle of your application lifecycle)
 * Define functions as non-configurable/non-writable in development mode
 to discover conflicts before pushing to production.

 This proposal does not aim at solving the problem of library conflicts
 which existed before this proposal and should be solve independently.

 David

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




 --
 Cheers,
 --MarkM





 --
 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-13 Thread Brendan Eich

Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
October 13, 2013 11:19 AM
Keeping a third parameter beyond object and property name seems 
unnecessary.


Here is a counterexample based on the strawman's syntax:

// In module LINQ's body:
  extension Array.prototype {
where: Array.prototype.filter,
select: Array.prototype.map
  }
  export function query(a, w, s) {
return a.where(w).select(s);
  }

import {query} from LINQ;

Array.prototype.select = () = oops;

var b = readData();
var w = ..., s = ...;
var r = query(b, w, s);

// So far, so good. Now let's try an array-like:
var c = { length: 0 };

// and let's be mean:

Object.prototype.where = () = oops for real!;

String.prototype.select = x = x; // identity function

// Fill c from b and query c with w and s:
b.forEach(e = c[c.length++] = e);
var s = query(c, w, s);

// This must hold:
assertEqual(s, oops for real!);

The only way to make this work is for the code in LINQ's body, in 
function query, to look for 'where' in 'a' (whose type is not known 
statically) by passing a token for the extended scope of module LINQ's body.


When 'a.where' is evaluated to call the method, if 'a' is an instance of 
Array.prototype with no shadowing 'where', in particular when it refers 
to 'b', then the extension method = Array.prototype.filter is found.


When 'a' refers to 'c', however, the code in LINQ does not know this _a 
priori_, so again the lookup of 'where' in c must pass the scope token. 
But this time, because c is an array-like Object instance that does not 
delegate to Array.prototype, the extension 'where' method is not found.


In my likely naive eyes, dynamic  `this` gives us great power here. 
Thinking about other languages that deal with the problem. As far as I 
remember C# extension methods are just (really nice) syntactic sugar 
for statics.


C# has static types and name lookup rules. JS has neither in full, 
although its name lookup rules are static within functions (and blocks 
in ES6), excluding 'with'.



Is it difficult to convert something like:

```
Array.prototype.last = function(){ return this[this.length-1] }
```

To something like

```
function Array$prototype$last(param1){ return (function(){ return 
this[this.length-1] }).call(param1); }

```

?
You have not defined convert, and there's no client code that calls 
'last' on a given array instance.


Another way of saying this: your name mangling does nothing to help an 
array ('b' in my example) find its method. There's no static type, no 
class or traits. The lookup in LINQ to call a.where is fully dynamic. 
Same for any use of your last method. The name rendezvous must be via 
prototypal lookup.


If you wrote client code in scope of the 'last' extension, e.g.

  var b = [1, 2, 3];
  alert(b.last());

and expected some whole-program transformation (which we do not perform 
in JS, too much ambiguity -- think of computed property names, never 
mind 'with' and the global object and eval!) that results in


  var b = [1, 2, 3];
  alert((b instanceof Array) ? Array$prototype$last.call(b) : b.last());

then you have essentially added the third (scope token) parameter by 
code expansion. Whether ?: or an if statement or polymorphic lookup is 
used, that's real added runtime cost, and it won't fly.


/be


-- Forwarded message --
From: Erik Arvidsson erik.arvids...@gmail.com 
mailto:erik.arvids...@gmail.com

To: Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com
Cc: es-discuss es-discuss@mozilla.org mailto:es-discuss@mozilla.org
Date: Sun, 13 Oct 2013 13:32:23 -0400
Subject: Re: Scoped binding of a method to an object
We did proposes this back in 2011

http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions

I wasn't at this actual F2F meeting so I don't know many details.
Brendan might remember what the blocking issue was?

___
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-13 Thread Brendan Eich

Erik Arvidsson wrote:
Let's not kid ourselves. WeakMaps have bad user ergonomics and runtime 
ergonomics. I think at this point non method functions are much better.


Hang on, relationships and new syntax can solve both performance and 
ergonomics concerns, we think.


Perhaps you missed the March meeting where Mark discussed relationships 
(big meeting, it may have been near or even over a break).


The key insight is that with:

  obj@rel
  obj@rel = val

we can avoid the dot dilemma of having to parameterize by scope, 
instead treat these two as


  rel.@@get(obj)
  rel.@@set(obj, val)

respectively, under the hood.

Mark observed further that where rel could be a weak map, it should not 
be implemented as an ephemeron table with all the GC costs that entails. 
Because such an object field relationship outlives all object 
instances, it is equivalent to a class or trait private member, and the 
value can be stored directly on the object.


The issue of proxy leaking is dodged by delegating to rel, which can 
itself by proxied in a membrane setting, IIRC.


But at this point I should summon Mark to take over. My point is that it 
seems not everyone heard Mark's statement that weakmaps should not be 
used to implement relationships except in preprocessors targeting ES6 
(assuming we get relationships into ES7).


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


Re: Generic Bundling

2013-10-13 Thread Brendan Eich

Anne van Kesteren mailto:ann...@annevk.nl
October 11, 2013 12:34 AM
On Fri, Oct 11, 2013 at 3:53 AM, Brendan Eichbren...@mozilla.com  wrote:

On Thu, Oct 10, 2013 at 8:10 PM, Andrea Giammarchi
andrea.giammar...@gmail.commailto:andrea.giammar...@gmail.com  wrote:

 You are confining the problem in HTTP only scenarios while the
 solution provided by

 script src=lib/main.js ref=”assets.zip”/script

No, you're right -- agree with you and Andrea, this is sweet.


It would require each end point that wants to support this to have new
syntax. A solution from http://wiki.whatwg.org/wiki/Zip#URLs will not
require updating all the end points.


That doc is a bit cryptic.

Can you explain how new URL syntax to address a ZIP member (I like, we 
had it in the ancient days with JAR files [ZIPs of course] using '!') 
avoids updating both end points? The content on the server starts using


script src=assets.zip!lib/main.js/script

How do old browsers cope?


HTML nerd nit: is ref the right name? I thought it was used as an
attribute name somewhere in HTML or nearby, but I can't find it. Cc'ing
Anne.


You might be thinking of rev (which is obsolete now in favor of
using rel everywhere).


That's it, thanks!

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


Re: Generic Bundling

2013-10-13 Thread Brendan Eich

Jorge Chamorro wrote:

On 11/10/2013, at 03:53, Brendan Eich wrote:
  

  On Thu, Oct 10, 2013 at 8:10 PM, Andrea Giammarchiandrea.giammar...@gmail.com  
mailto:andrea.giammar...@gmail.com  wrote:
  
  You are confining the problem in HTTP only scenarios while the

  solution provided by
  
  script src=lib/main.js ref=”assets.zip”/script
  
  
  No, you're right -- agree with you and Andrea, this is sweet.


Are main.js and assets.zip two separate files, or is main.js expected to come 
from into assets.zip?


The latter.


  I think the latter would be best because it would guarantee that the assets 
are there by the time main.js runs, as if they were local files, ready to be 
require()d synchronously.


How would old browsers cope, though? They would load only lib/main.js 
(and possibly make a request storm, as Russell brought out elsewhere in 
this thread), so (synchronous) require of another member of assets.zip 
might or might not work.


A prefetching link element might not suffice in old browsers, I'm 
pretty sure it won't.


If the only way to cope with downrev browsers is to use Traceur, so be 
it. We just need to be sure we're not missing some clever alternative.


/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-13 Thread Erik Arvidsson
On Oct 13, 2013 3:23 PM, Brendan Eich bren...@mozilla.com wrote:

 Erik Arvidsson wrote:

 Let's not kid ourselves. WeakMaps have bad user ergonomics and runtime
ergonomics. I think at this point non method functions are much better.


 Hang on, relationships and new syntax can solve both performance and
ergonomics concerns, we think.

 Perhaps you missed the March meeting where Mark discussed relationships
(big meeting, it may have been near or even over a break).

I did not miss it.

 The key insight is that with:

   obj@rel
   obj@rel = val

 we can avoid the dot dilemma of having to parameterize by scope,
instead treat these two as

   rel.@@get(obj)
   rel.@@set(obj, val)

 respectively, under the hood.

 Mark observed further that where rel could be a weak map, it should not
be implemented as an ephemeron table with all the GC costs that entails.
Because such an object field relationship outlives all object instances,
it is equivalent to a class or trait private member, and the value can be
stored directly on the object.

Using a WeakMap for rel is a bit too simplistic. We need to read and write
through to the prototype but you are right that rel can be implemented
using WeakMaps.

 The issue of proxy leaking is dodged by delegating to rel, which can
itself by proxied in a membrane setting, IIRC.

 But at this point I should summon Mark to take over. My point is that it
seems not everyone heard Mark's statement that weakmaps should not be used
to implement relationships except in preprocessors targeting ES6 (assuming
we get relationships into ES7).

Exactly.
___
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-13 Thread Rick Waldron
On Sun, Oct 13, 2013 at 12:45 PM, Kevin Smith zenpars...@gmail.com wrote:


 This is trivial with Symbols:

   let shuffle = Symbol();

   Array.prototype[shuffle] = function() {...};


 Only code that has access to the `shuffle` symbol may use the method:

   let shuffled = array[shuffle]();


 Unfortunately, such a construction will fail in a multi-realm (i.e.
 multiple frames) environment.


Not if I register the symbol in the not-yet-specified symbol registry.

Rick
___
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-13 Thread Brendan Eich

Erik Arvidsson wrote:


... My point is that it seems not everyone heard Mark's statement 
that weakmaps should not be used to implement relationships except in 
preprocessors targeting ES6 (assuming we get relationships into ES7).


Exactly.



Ok, that's what I was hoping for. We need Traceur, not poorly-performing 
and unergonomic by-hand codings.


To borrow from Dean Wormer: slow, hard to read, and hard to write is no 
way to go through life! ;-)


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


Re: Generic Bundling

2013-10-13 Thread Andrea Giammarchi
my latest message was about this situation

www/
  my-assets/
js/
  my-bundle.js
css/
  some.css
image/
  some.png

  assets.zip

where latter contains the equivalent of the my-assets folder.

The prefetching link won't do a thing in old browsers, might be a directive
for modern suggesting a package.zip file to use instead of the folder name.

Old browsers will do everything as they do today, new browsers have the
ability to use one single package instead of requiring the file.

As result:

link rel=package name=my-assets type=application/zip href
=assets.zip
script src=my-assets/js/my-bundle.js/script

will simply request that file through HTTP in old browsers, it will use the
aliased zip file through my-assets if capable.

It's actually very similar to initial proposal also creating a precedent
for network aliases independent from mod_rewrite and friends (client/UA
only mod_rewrite like approach)

Cheers









On Sun, Oct 13, 2013 at 12:34 PM, Brendan Eich bren...@mozilla.com wrote:

 Jorge Chamorro wrote:

 On 11/10/2013, at 03:53, Brendan Eich wrote:

 

   On Thu, Oct 10, 2013 at 8:10 PM, Andrea Giammarchi
 andrea.giammarchi@**gmail.com andrea.giammar...@gmail.com  mailto:
 andrea.giammarchi@**gmail.com andrea.giammar...@gmail.com  wrote:
 You are confining the problem in HTTP only scenarios while
 the
   solution provided by
 script src=lib/main.js ref=”assets.zip”/script
 

 No, you're right -- agree with you and Andrea, this is sweet.


 Are main.js and assets.zip two separate files, or is main.js expected to
 come from into assets.zip?


 The latter.


I think the latter would be best because it would guarantee that the
 assets are there by the time main.js runs, as if they were local files,
 ready to be require()d synchronously.


 How would old browsers cope, though? They would load only lib/main.js (and
 possibly make a request storm, as Russell brought out elsewhere in this
 thread), so (synchronous) require of another member of assets.zip might or
 might not work.

 A prefetching link element might not suffice in old browsers, I'm pretty
 sure it won't.

 If the only way to cope with downrev browsers is to use Traceur, so be it.
 We just need to be sure we're not missing some clever alternative.

 /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-13 Thread Peter Seliger
If you really have to live with those restriction you do describe,
there still is a low level solution working since ES 3 that keeps
the implemented codebase of certain behaviors at one place
without effecting any other code - function based traits and mixins.

One could e.g. write ones own implementations of an
Enumerable's [first], [last] accessors.


var Enumerable_first_last = (function () {

  var
Trait,

first = function () {
  return this[0];
},
last = function () {
  return this[this.length - 1];
}
  ;

  Trait = function () {

this.first = first;
this.last = last;
  };

  return Trait;

}());

From that point one is free to decide of where to apply that trait.

var
  str = JavaScript natively supports Traits,
  arr = str.split( ),
  coll = {
0: foo,
1: bar,
2: baz,
length: 2
  }
;

It is totally fine to apply additional behavior separately to objects
that are in need of it.

Enumerable_first_last.call(arr);

arr.first(); // JavaScript
arr.last(); // Traits

Enumerable_first_last.call(coll);

coll.first(); // foo
coll.last(); // bar

One also could delegate this behavior to an objects prototype.

Enumerable_first_last.call(String.prototype);
 // works for all [[String]] implementations that do allow access via [idx]

str.first(); // J
str.last(); // s

This approach in its first step decouples implementation from
having it directly effecting a system. The second step is about
responsibility and making decisions.

Peter



On Sun, Oct 13, 2013 at 8:47 PM, Benjamin (Inglor) Gruenbaum 
ing...@gmail.com wrote:

  Prollyfilling is great too (perhaps you disagree?), and as its name
 suggests it happens *before* the method is added to the spec.

 So in your opinion adding a `.shuffle` method to an Array in a library I
 ship to users is a good idea if it makes my code clearer and nicer?

 I'm not saying I disagree, I'm not one of those people who passes an extra
 parameter for `undefined` in a function. I just think it can be very risky.

 When I have to work on big code bases that run JavaScript end to end using
 multiple frameworks and libraries on both sides, I find that extending
 object prototypes can be _very_ risky - and Prollyfilling (nice term by
 the way) has bitten me before. Sure, in _my_ code it can be very nice, but
 I expect libraries to have little to no side effects on my code and that's
 exactly the cases it can bite me.

  How exactly did that example fail? The differences in detail hardly
 matter; PrototypeJS trod a cow-path that ES5 paved. Most users don't worry
 about the edge case differences.

 I don't think anyone today is doubting the enormous contribution
 PrototypeJS had and `.bind` was very useful in it and is very useful in
 ES5. However, running into edge cases and getting unexpected results is
 something I don't think people appreciate. The SweetJS case is just as
 interesting.

 There is no doubt some of the most interesting API additions have come
 from people extending natives and that says something. However, today when
 rather than writing 1000 line pages I see more and more 100 thousand lines
 code bases using multiple libraries - side effects that extending natives
 sound _very_ scary, and being able to extend the natives in a way that does
 not bite me is something I'd _really_ love to play with.

  Don't worry about syntax yet.

 Of course, I was just toying around. Like I've said before, pretty much
 anyone else in this discussion is more qualified to come with an actual
 solution than me.

  This must cost, and it does cost.

 Would you mind elaborating on that or linking to relevant discussion about
 the last proposal? I'd love to understand the issues involved and get a
 better understanding of the challenges something like this would bring.




 On Sun, Oct 13, 2013 at 9:37 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 13, 2013 11:00 AM

 Brendan Eichbren...@mozilla.com mailto:bren...@mozilla.com wrote:
  No, object detection, polyfilling, and even prollyfilling are common
 and successful adaptationsp on the Web.

 Polyfilling is great _after_ the method has already been added to the
 spec.


 Prollyfilling is great too (perhaps you disagree?), and as its name
 suggests it happens *before* the method is added to the spec.


  I'm completely fine with adding an Array.prototype.map shim to IE8, the
 problem with adding a method that's not on the prototype yet is that it'll
 fail in case the spec is different from the implementation I chose. If you
 mentioned PrototypeJS, its `.bind` method is one such example.


 How exactly did that example fail? The differences in detail hardly
 matter; PrototypeJS trod a cow-path that ES5 paved. Most users don't worry
 about the edge case differences.


   Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension 

Re: Scoped binding of a method to an object

2013-10-13 Thread Benjamin (Inglor) Gruenbaum
Thanks, this really helped me understand the underlying issue here forcing
dynamic resolution of scope here. It sounds a lot harder than I initially
thought

I have to say the fact this is so deeply rooted in the language semantics
is somewhat surprising to me. That said, I think I see why behavioral
typing would be act like this and I expect this to still be a lot harder
than I imagine.

 Here is a counterexample based on the strawman's syntax:
 ...

When I pass a parameter `a` to a function and call `a.where` , whether or
not it's an extension method - don't I still have to do dynamic scope
resolution? Doesn't it still have to walk the prototype chain until I find
`.where` - just like if I pass an array-like with `.splice` and send it to
a method using it and it has to figure out it's not Array.prototype.splice?

Off the top of my head - what about for the duration of the scope of these
methods we  have a prototype right after Array.prototype - in this
scenario. Doesn't this make `c` go to Object.prototype.where and then
String.prototype.select and all `b` does is another prototype chain look up
before reaching the extension? This is probably another naive suggestion
though.




On Sun, Oct 13, 2013 at 10:15 PM, Brendan Eich bren...@mozilla.com wrote:

 Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 13, 2013 11:19 AM

 Keeping a third parameter beyond object and property name seems
 unnecessary.


 Here is a counterexample based on the strawman's syntax:

 // In module LINQ's body:
   extension Array.prototype {
 where: Array.prototype.filter,
 select: Array.prototype.map
   }
   export function query(a, w, s) {
 return a.where(w).select(s);
   }

 import {query} from LINQ;

 Array.prototype.select = () = oops;

 var b = readData();
 var w = ..., s = ...;
 var r = query(b, w, s);

 // So far, so good. Now let's try an array-like:
 var c = { length: 0 };

 // and let's be mean:

 Object.prototype.where = () = oops for real!;

 String.prototype.select = x = x; // identity function

 // Fill c from b and query c with w and s:
 b.forEach(e = c[c.length++] = e);
 var s = query(c, w, s);

 // This must hold:
 assertEqual(s, oops for real!);

 The only way to make this work is for the code in LINQ's body, in function
 query, to look for 'where' in 'a' (whose type is not known statically) by
 passing a token for the extended scope of module LINQ's body.

 When 'a.where' is evaluated to call the method, if 'a' is an instance of
 Array.prototype with no shadowing 'where', in particular when it refers to
 'b', then the extension method = Array.prototype.filter is found.

 When 'a' refers to 'c', however, the code in LINQ does not know this _a
 priori_, so again the lookup of 'where' in c must pass the scope token. But
 this time, because c is an array-like Object instance that does not
 delegate to Array.prototype, the extension 'where' method is not found.


  In my likely naive eyes, dynamic  `this` gives us great power here.
 Thinking about other languages that deal with the problem. As far as I
 remember C# extension methods are just (really nice) syntactic sugar for
 statics.


 C# has static types and name lookup rules. JS has neither in full,
 although its name lookup rules are static within functions (and blocks in
 ES6), excluding 'with'.


  Is it difficult to convert something like:

 ```
 Array.prototype.last = function(){ return this[this.length-1] }
 ```

 To something like

 ```
 function Array$prototype$last(param1){ return (function(){ return
 this[this.length-1] }).call(param1); }
 ```

 ?

 You have not defined convert, and there's no client code that calls
 'last' on a given array instance.

 Another way of saying this: your name mangling does nothing to help an
 array ('b' in my example) find its method. There's no static type, no class
 or traits. The lookup in LINQ to call a.where is fully dynamic. Same for
 any use of your last method. The name rendezvous must be via prototypal
 lookup.

 If you wrote client code in scope of the 'last' extension, e.g.

   var b = [1, 2, 3];
   alert(b.last());

 and expected some whole-program transformation (which we do not perform in
 JS, too much ambiguity -- think of computed property names, never mind
 'with' and the global object and eval!) that results in

   var b = [1, 2, 3];
   alert((b instanceof Array) ? Array$prototype$last.call(b) : b.last());

 then you have essentially added the third (scope token) parameter by code
 expansion. Whether ?: or an if statement or polymorphic lookup is used,
 that's real added runtime cost, and it won't fly.

 /be


 -- Forwarded message --
 From: Erik Arvidsson erik.arvids...@gmail.com mailto:
 erik.arvidsson@gmail.**com erik.arvids...@gmail.com
 To: Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com
 Cc: es-discuss es-discuss@mozilla.org mailto:es-discuss@mozilla.org**
 Date: Sun, 13 Oct 2013 13:32:23 -0400
 Subject: Re: Scoped binding of a method to an object

Re: Scoped binding of a method to an object

2013-10-13 Thread Benjamin (Inglor) Gruenbaum
Function traits and mixins are the bread and butter of JS. Being able to
share functionality is the pumping heart of prototypical inheritance,
especially in a behaviorally typed environment.

Much like a possible issue I have with what Rick suggested (although mixins
and decoration are not the same)  -  let's say you have `
Enumerable_first_last.call(arr)` , and then I `.map` or `.filter` that
mixed in array - the resulting array no longer has the trait.

I can of course call Object.mixin on the result of `.map` and override
`.map` on a Enumerable_first_last but that's a tedious process I don't want
to have to do for every trait (what if I add several? Do I now have to keep
track and compose?)

It's an interesting suggestion and a common pattern, but I really hope we
can do better.



On Mon, Oct 14, 2013 at 12:01 AM, Peter Seliger 
peter.seli...@googlemail.com wrote:

 If you really have to live with those restriction you do describe,
 there still is a low level solution working since ES 3 that keeps
 the implemented codebase of certain behaviors at one place
 without effecting any other code - function based traits and mixins.

 One could e.g. write ones own implementations of an
 Enumerable's [first], [last] accessors.


 var Enumerable_first_last = (function () {

   var
 Trait,

 first = function () {
   return this[0];
 },
 last = function () {
   return this[this.length - 1];
 }
   ;

   Trait = function () {

 this.first = first;
 this.last = last;
   };

   return Trait;

 }());

 From that point one is free to decide of where to apply that trait.

 var
   str = JavaScript natively supports Traits,
   arr = str.split( ),
   coll = {
 0: foo,
 1: bar,
 2: baz,
 length: 2
   }
 ;

 It is totally fine to apply additional behavior separately to objects
 that are in need of it.

 Enumerable_first_last.call(arr);

 arr.first(); // JavaScript
 arr.last(); // Traits

 Enumerable_first_last.call(coll);

 coll.first(); // foo
 coll.last(); // bar

 One also could delegate this behavior to an objects prototype.

 Enumerable_first_last.call(String.prototype);
  // works for all [[String]] implementations that do allow access via [idx]

 str.first(); // J
 str.last(); // s

 This approach in its first step decouples implementation from
 having it directly effecting a system. The second step is about
 responsibility and making decisions.

 Peter



 On Sun, Oct 13, 2013 at 8:47 PM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com wrote:

  Prollyfilling is great too (perhaps you disagree?), and as its name
 suggests it happens *before* the method is added to the spec.

 So in your opinion adding a `.shuffle` method to an Array in a library I
 ship to users is a good idea if it makes my code clearer and nicer?

 I'm not saying I disagree, I'm not one of those people who passes an
 extra parameter for `undefined` in a function. I just think it can be very
 risky.

 When I have to work on big code bases that run JavaScript end to end
 using multiple frameworks and libraries on both sides, I find that
 extending object prototypes can be _very_ risky - and Prollyfilling (nice
 term by the way) has bitten me before. Sure, in _my_ code it can be very
 nice, but I expect libraries to have little to no side effects on my code
 and that's exactly the cases it can bite me.

  How exactly did that example fail? The differences in detail hardly
 matter; PrototypeJS trod a cow-path that ES5 paved. Most users don't worry
 about the edge case differences.

 I don't think anyone today is doubting the enormous contribution
 PrototypeJS had and `.bind` was very useful in it and is very useful in
 ES5. However, running into edge cases and getting unexpected results is
 something I don't think people appreciate. The SweetJS case is just as
 interesting.

 There is no doubt some of the most interesting API additions have come
 from people extending natives and that says something. However, today when
 rather than writing 1000 line pages I see more and more 100 thousand lines
 code bases using multiple libraries - side effects that extending natives
 sound _very_ scary, and being able to extend the natives in a way that does
 not bite me is something I'd _really_ love to play with.

  Don't worry about syntax yet.

 Of course, I was just toying around. Like I've said before, pretty much
 anyone else in this discussion is more qualified to come with an actual
 solution than me.

  This must cost, and it does cost.

 Would you mind elaborating on that or linking to relevant discussion
 about the last proposal? I'd love to understand the issues involved and get
 a better understanding of the challenges something like this would bring.




 On Sun, Oct 13, 2013 at 9:37 PM, Brendan Eich bren...@mozilla.comwrote:

 Benjamin (Inglor) Gruenbaum mailto:ing...@gmail.com
 October 13, 2013 11:00 AM

 Brendan Eichbren...@mozilla.com mailto:bren...@mozilla.com wrote:
  No, object detection, 

Re: Scoped binding of a method to an object

2013-10-13 Thread Till Schneidereit
On Sun, Oct 13, 2013 at 8:40 PM, Brendan Eich bren...@mozilla.com wrote:
 Till Schneidereit mailto:t...@tillschneidereit.net
 October 13, 2013 11:28 AM

 And now it causes problem for TC39, browser vendors, sites that use it and
 end users. (The last group should be affected the least because the first
 three groups work together to prevent it, of course.)


 I think we agree. My point was that the objections are not definitive, not
 axiomatic enough. The costs are born later and by others. This is a
 recipe for social ills.

Ok, we do agree, then.


 What we do about it is up to us, but just asserting that developers should
 stop extending primordials sounds like King Canute to me.

Also agreed.

It's still not entirely obvious to me what exactly we should do about
it, sadly. And not only now, but going forward. Cow path paving
requires the cows' ability to trod on the same ground that might be
paved later. That very fact means that the cow paths might end up
colliding with paved streets. I don't see how this basic conundrum can
be resolved without a scope based resolution-mechanism (no pun
intended).
___
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-13 Thread Benjamin (Inglor) Gruenbaum
This sort of decoration is nice and it's how I usually do this right now,
but this requires me to wrap every array with an `XArray` call which is
tedious, not to mention stuff like `.map` or `.reduce` would still return
an Array which would result in more endless wrapping.


On Sun, Oct 13, 2013 at 11:53 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Sun, Oct 13, 2013 at 2:00 PM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com wrote:

 Brendan Eich bren...@mozilla.com wrote:
  No, object detection, polyfilling, and even prollyfilling are common
 and successful adaptationsp on the Web.

 Polyfilling is great _after_ the method has already been added to the
 spec. I'm completely fine with adding an Array.prototype.map shim to IE8,
 the problem with adding a method that's not on the prototype yet is that
 it'll fail in case the spec is different from the implementation I chose.
 If you mentioned PrototypeJS, its `.bind` method is one such example.

  Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension properties.

 I have to say this surprises me, a performance issue is the last thing I
 expected. What about attaching a prototype as a closure variable, something
 (and this is a syntax I __don't__ like) like:
 ```
 (function(use Array){
 Array.prototype.contains = function() { ...
 ...
 // any code here has access to .contains, code that did not originate
 here does not have such access, much like a closure.
 // other code is free to use Array without any collisions.
 })()
 ```


 Another solution is creating your own subclass with custom methods...


 class XArray extends Array {
constructor(...args) {
  super(...args);
}
contains(arg) { ... }
 }


 Then all code in this application uses XArray and gets its custom
 contains


 Rick


___
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-13 Thread Rick Waldron
On Sunday, October 13, 2013, Benjamin (Inglor) Gruenbaum wrote:

 This sort of decoration is nice and it's how I usually do this right now,
 but this requires me to wrap every array with an `XArray` call which is
 tedious,


What do you mean by wrap? Using this looks like:

let values = new XArray(1,2,3,4);

values.contains(3); // this is the custom contains


 not to mention stuff like `.map` or `.reduce` would still return an Array


That's incorrect. XArray.prototype.map would return an XArray instance and
reduce always returns what you specify it to return, which can be anything.


Rick


 which would result in more endless wrapping.


 On Sun, Oct 13, 2013 at 11:53 PM, Rick Waldron 
 waldron.r...@gmail.comjavascript:_e({}, 'cvml', 'waldron.r...@gmail.com');
  wrote:




 On Sun, Oct 13, 2013 at 2:00 PM, Benjamin (Inglor) Gruenbaum 
 ing...@gmail.com javascript:_e({}, 'cvml', 'ing...@gmail.com'); wrote:

 Brendan Eich bren...@mozilla.com javascript:_e({}, 'cvml',
 'bren...@mozilla.com'); wrote:
  No, object detection, polyfilling, and even prollyfilling are
 common and successful adaptationsp on the Web.

 Polyfilling is great _after_ the method has already been added to the
 spec. I'm completely fine with adding an Array.prototype.map shim to IE8,
 the problem with adding a method that's not on the prototype yet is that
 it'll fail in case the spec is different from the implementation I chose.
 If you mentioned PrototypeJS, its `.bind` method is one such example.

  Your subject recalls a defunct proposal to add lexically-scoped but
 heap-based -- therefore object property-lookup performance hindering --
 extension properties.

 I have to say this surprises me, a performance issue is the last thing I
 expected. What about attaching a prototype as a closure variable, something
 (and this is a syntax I __don't__ like) like:
 ```
 (function(use Array){
 Array.prototype.contains = function() { ...
 ...
 // any code here has access to .contains, code that did not
 originate here does not have such access, much like a closure.
 // other code is free to use Array without any collisions.
 })()
 ```


 Another solution is creating your own subclass with custom methods...


 class XArray extends Array {
constructor(...args) {
  super(...args);
}
contains(arg) { ... }
 }


 Then all code in this application uses XArray and gets its custom
 contains


 Rick




___
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-13 Thread Till Schneidereit
On Sun, Oct 13, 2013 at 11:50 PM, Domenic Denicola
dome...@domenicdenicola.com wrote:
 From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of 
 Benjamin (Inglor) Gruenbaum

 not to mention stuff like `.map` or `.reduce` would still return an Array 
 which would result in more endless wrapping.

 This is actually not true as of ES6; ES6 uses `this.constructor` to figure 
 out how to create the returned instance, which means inherited versions of 
 `map`/`reduce`/etc. will automatically return new `XArray`s.

 It's quite a clever trick IMO, so we should all thank Allen for pushing for 
 it and doing the spec work to make it possible :)

Here's to hoping that it'll actually work in practice and not break
too many sites.
___
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-13 Thread Benjamin (Inglor) Gruenbaum
Yeah, I don't see how it's going to happen either. Now that I get you meant
dynamic as in contrary to lexical scoping having scoped object extensions
seems very counter intuitive - especially given the direction the language
is heading.

Thanks for the discussion.


On Mon, Oct 14, 2013 at 1:36 AM, Brendan Eich bren...@mozilla.com wrote:

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

 Thanks, this really helped me understand the underlying issue here
 forcing dynamic resolution of scope here. It sounds a lot harder than I
 initially thought

 I have to say the fact this is so deeply rooted in the language semantics
 is somewhat surprising to me. That said, I think I see why behavioral
 typing would be act like this and I expect this to still be a lot harder
 than I imagine.

  Here is a counterexample based on the strawman's syntax:
  ...

 When I pass a parameter `a` to a function and call `a.where` , whether or
 not it's an extension method - don't I still have to do dynamic scope
 resolution?


 That's not dynamic scope, first (dynamic scope refers to scoping where
 an *unqualified* name's meaning cannot be determined lexically -- e.g.,
 with or the global object in JS; inline event handlers in the DOM).


  Doesn't it still have to walk the prototype chain until I find `.where` -
 just like if I pass an array-like with `.splice` and send it to a method
 using it and it has to figure out it's not Array.prototype.splice?


 Of course. The meaning a dot-qualified name in JS indeed depends on
 prototype lookup. But the parameters to that lookup procedure are the
 starting (directly referenced) object and the property name -- and not the
 scope in addition, or any equivalent transformation (e.g., my ?: example --
 not also it used instanceof and did not work when a direct shadowing method
 existed on the array).


  Off the top of my head - what about for the duration of the scope of
 these methods we  have a prototype right after Array.prototype - in this
 scenario. Doesn't this make `c` go to Object.prototype.where and then
 String.prototype.select and all `b` does is another prototype chain look up
 before reaching the extension? This is probably another naive suggestion
 though.


 It is, if you mean dynamically altering the prototype chain of standard
 objects within a lexical extent. That does create dynamic scope, since the
 call graph is not statically decidable in general in JS, and calls out of
 the lexical extent would see the prototype chain extension too. Even if we
 could pin down the call graph, we do not want arbitrary mutations going in
 and out of scope of prototype chains.

 Anyway, I think at this point we've established what is required for any
 scoped object extensions. Please draw the conclusion.

 /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-13 Thread Rick Waldron
On Sunday, October 13, 2013, Brendan Eich wrote:

 Till Schneidereit wrote:

 OnSun, Oct 13, 2013  at 11:50 PM,  Domenic Denicola
 dome...@domenicdenicola.com  wrote:

   From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf
 Of Benjamin (Inglor) Gruenbaum
 

   not to mention stuff like `.map` or `.reduce` would still return an
 Array which would result in more endless wrapping.

 
   This is actually not true as of ES6; ES6 uses `this.constructor` to
 figure out how to create the returned instance, which means inherited
 versions of `map`/`reduce`/etc. will automatically return new `XArray`s.
 
   It's quite a clever trick IMO, so we should all thank Allen for
 pushing for it and doing the spec work to make it possible:)


 Here's to hoping that it'll actually work in practice and not break
 too many sites.


 Yes, we are not nearly out of the woods on this one.

 In fact, at the September TC39 meeting, did we not agree that more work
 was needed, and to go back to the lab? Allen (editor) and Rick (notes
 taker) know.


The work that remained was wrapped up in draft 19, published sept 27th.
Allen should confirm (as always)

Rick


 /be

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