Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-30 Thread Allen Wirfs-Brock
A bit on Object.extend(obj,{...}) vs. obj.{...}

To get started, just a reminder that we can't really compare the two based on 
the assumption that the second argument to extend is an object literal as there 
is no way to syntactically guarantee that.  We have to assume that both 
arguments to Object.extend are preexisting object that were created in some 
arbitrary manner.  EG, we are have to compare Object.extend(obj1, obj2) vs. 
obj1.{...}


On Apr 29, 2012, at 10:10 AM, Axel Rauschmayer wrote:

 ...
 Object.extend would automatically invoke Object.defineMethod() (or similar) 
 for you, to enable super-references (but I doubt there is much use for them 
 in mixins).

Mixin's and inheritance (including) super references are orthogonal concepts.  
Some may choose to use only one or the other but they really need to be 
composable for for those who need to use them in combination. 

The defineMethod point is important.  Equally important is the treatment of 
private named properties.

To correctly preserve super invocation semantics methods must be processed 
using Object.defineMethod when they are copied from obj2 to obj1.   For 
obj1.{...} this isn't a problem because the extension object and its 
properties don't preexist.  They are  just syntax that is processed just like 
creating completely new properties on obj1 and the semantic rules for those new 
properties are exactly the same as those that would have been used in an object 
literal that was providing the initial definition of obj1.  There is no copying 
semantics of worry about.

One of the syntactic distinctions that is made by obj1.{...}  is the difference 
between a method property and a function valued state property.  Consider:

//somewhere else in the program
vender.getSomeCallback = function(a,b) {
let cb=  function() 
{...myWeakMap.get(cb).attachment...this.something(a,b)};
myWeakMap.set(cb, generateAttachment(a,b));
return cb;
}

//main example
obj1.{
   callback: vender.getSomeCallback(x,y),
   meth() {
   super.meth();
   this.callback.call(this.target);
 }
   
Note that .{ sees the callback property as a regular state property and 
doesn't use defineMethod semantics to create  it on obj1. The value returned by 
vender.getSomeCallback is directly used as the value of the callback state 
property and the identify based annotation mechanism used in the definition of 
the callback will work just fine.  meth, because it is expressed using concise 
method syntax is processed as a new method definition that is super bound as if 
by defineMethod to obj1.

Now consider using extend:

let obj2 = {
   callback: vender.getSomeCallback(x,y),
   meth() {
   super.meth();
   this.callback.call(this.target);
 };

Object.extend(obj1,obj2);

Object.extend doesn't have any visibility of how the properties of obj2 were 
defined. All it sees is two data properties whose values are functions.  It if 
used Object.defineProperty to process both properties then methwould be super 
bound to the wrong object. If it used Object.defineMethod on both properties 
then the callback function's identify may change.  What Object.extend will have 
to do is have a heuristic (if the value is  super bound to obj2, then 
defineMethod it to obj1.  Otherwise, just use defineProperty) that it applies 
to function valued data properties.   This heuristic  should be adequate for 
uses that correspond to what could be expressed using .{ but it also allows 
other cases where the heuristic may produce something other than the desired 
result.  Those situations simply don't exist for .{

Use of private names with Object.extend is even more problematic. 

Consider something like:

let MixinArrayIterator = (obj) = obj.{
   @iterator() {
  let coll = this;
  return function*() {...yield coll[...}
}
}
   
which uses the built-in @iterator private name.  This works nicely with  .{ 
because the private name is used within the .{ special form and doesn't require 
any runtime reflection on the mixin object.  However, to do the same with 
Object.extend would requires that extend has reflective visibility of actual 
private named properties of obj2. The reflection restrictions on private names 
exists to support various high-integrity use cases.  In this particular 
situation, there is nothing actually private in the hight-integrity sense 
about @iterator.  To make this all work with extend we would probably have to 
re-introduce  the concept of unique names which are like private names but 
without the reflection restrictions. That then would introduces additional 
complexities.

It is probably possible to support mixin attachment using a  functional form 
(Object.extend) rather than using a special form (.{} ) but there is a lot more 
to it than just a simply syntactic substitutions. 

Allen

___
es-discuss mailing list
es-discuss@mozilla.org

Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich

Axel Rauschmayer wrote:

I am not saying that the transition from the old rules to the new rules will be 
entirely painless, but if the new rules are simple, that pain is worth it, IMHO.


There are no new rules. Some functions ignore |this| or bind it rather 
than using it. These differences in kind do not change due to arrows.



  Library code might need to go to extra lengths to help normal developers with 
the transition (error messages, different behavior, tool functions, etc.) and – 
to be explicit – might need a predicate such as `isArrowFunction` (which should 
only ever be used under the hood and thus would not increase confusion for 
library*users*).


There's no point in such a misnamed predicate. Today we have functions 
that ignore or bind |this|, as well as those that use |this| passed by 
the caller. Code requires and assumes one kind or another and does not 
test (and most programmers wouldn't cover all cases, and shouldn't have to).


Part of an API, an essential part of the contract, is any function 
parameter's |this| binding. Arrows make it easier to use callbacks 
wanting lexical |this| or not using |this| at all. This covers a large 
cohort. Code invoking the arrow is not going to test well or at all and 
do something helpful, or unhelpful such as throwing an exception.


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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Axel Rauschmayer
With “rules”, I don’t mean rules in the sense of the language spec, but rather 
rules for teaching the language to newcomers.

On Apr 29, 2012, at 10:28 , Brendan Eich wrote:

 Axel Rauschmayer wrote:
 I am not saying that the transition from the old rules to the new rules will 
 be entirely painless, but if the new rules are simple, that pain is worth 
 it, IMHO.
 
 There are no new rules. Some functions ignore |this| or bind it rather than 
 using it. These differences in kind do not change due to arrows.
 
  Library code might need to go to extra lengths to help normal developers 
 with the transition (error messages, different behavior, tool functions, 
 etc.) and – to be explicit – might need a predicate such as 
 `isArrowFunction` (which should only ever be used under the hood and thus 
 would not increase confusion for library*users*).
 
 There's no point in such a misnamed predicate. Today we have functions that 
 ignore or bind |this|, as well as those that use |this| passed by the caller. 
 Code requires and assumes one kind or another and does not test (and most 
 programmers wouldn't cover all cases, and shouldn't have to).
 
 Part of an API, an essential part of the contract, is any function 
 parameter's |this| binding. Arrows make it easier to use callbacks wanting 
 lexical |this| or not using |this| at all. This covers a large cohort. Code 
 invoking the arrow is not going to test well or at all and do something 
 helpful, or unhelpful such as throwing an exception.
 
 /be
 

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Angus Croll




On Apr 28, 2012, at 22:24, Axel Rauschmayer a...@rauschma.de wrote:

 The following two rules should be everything one has to know regarding 
 callable entities, in ES.next:
 1. Method: `this` is an implicit parameter = use a method definition.
 2. Non-method function: `this` is not an implicit parameter = use an arrow 
 function.
 
 In this light, I’d rewrite Kevin’s code slightly, because, conceptually, 
 `localStorage ` is a non-method function:
  const localStorage = (obj) = {
 
Object.extend(obj, {

If I understand correctly, this approach negates the need for a mixin function 
entirely - localStorage could just be an old style mixin hash. 

But either way this tosses out the benefits I get from functional mixins. By 
invoking the mixin instead of copying it I can a) customize it's behavior by 
passing it arguments b) have the mixin add advice (before, after, around) to 
functions of the target object.


 I think Angus’ most important point is this:
 
 Yes, people get confused by this binding; even though it is not hard to 
 learn the rules, and I know them very well, I still trip over them 
 sometimes. But unless we are going to introduce a hella strict mode that 
 reverts all previous rules of |this| binding, yet another rule will just add 
 to the morass.
 
 It would be my hope that we can replace all previous rules with the two rules 
 above. `apply` will mostly be replaced by the spread operator, `call` will 
 mostly be replaced by calling a value. Some code such as `forEach` 
 implementations that previously needed to use `call` to simulate lexical 
 scoping don’t need a `thisValue` parameter for array functions.

I admire the vision but in reality the boundary between ES5 and ES6 will be 
messy and drawn out - there will be no clear cut switching point. Legacy code 
must live alongside the new vision. Without a new strict mode which banishes 
much of the old spec (and kills my functional mixins) I'm finding it hard not 
to picture chaos. (and how do you shim = anyway?)

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Angus Croll




On Apr 29, 2012, at 1:28, Brendan Eich bren...@mozilla.org wrote:

 Axel Rauschmayer wrote:
 I am not saying that the transition from the old rules to the new rules will 
 be entirely painless, but if the new rules are simple, that pain is worth 
 it, IMHO.
 
 There are no new rules. Some functions ignore |this| or bind it rather than 
 using it. These differences in kind do not change due to arrows.

Is there lexical |this| binding in ES5?

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Axel Rauschmayer
 If I understand correctly, this approach negates the need for a mixin 
 function entirely - localStorage could just be an old style mixin hash. 
 
 But either way this tosses out the benefits I get from functional mixins. By 
 invoking the mixin instead of copying it I can a) customize it's behavior by 
 passing it arguments b) have the mixin add advice (before, after, around) 
 to functions of the target object.

For me, conceptually, localStorage() is a non-method function that has a single 
parameter. I don’t think the capabilities are impaired if you change each 
occurrence of:
 this.foo = function (...} {...};
to
Object.extend(obj, {
...
foo(...) { ... },
...
});

Object.extend would automatically invoke Object.defineMethod() (or similar) for 
you, to enable super-references (but I doubt there is much use for them in 
mixins).

Admittedly, if there is only a single method then there is a lot of unnecessary 
syntactic noise. However, methods tend to appear in groups (implementing 
protocols). Putting such groups in object literals makes much sense.

As an aside: If you want to annotate methods then function expressions are 
indeed a plus, because they can be immediately invoked. Python has method 
decorators for this [1].

myExtend(obj, { someMethod: function (inner, arg) { doSomething(); var result = 
inner(arg); result++; return result }.around() });

A bit hacky, but nicely declarative. Function.prototype.around() would tag the 
method, later post-processing would perform the transformation.

[1] http://www.python.org/dev/peps/pep-0318/

 It would be my hope that we can replace all previous rules with the two 
 rules above. `apply` will mostly be replaced by the spread operator, `call` 
 will mostly be replaced by calling a value. Some code such as `forEach` 
 implementations that previously needed to use `call` to simulate lexical 
 scoping don’t need a `thisValue` parameter for array functions.
 
 I admire the vision but in reality the boundary between ES5 and ES6 will be 
 messy and drawn out - there will be no clear cut switching point. Legacy code 
 must live alongside the new vision. Without a new strict mode which banishes 
 much of the old spec (and kills my functional mixins) I'm finding it hard not 
 to picture chaos. (and how do you shim = anyway?)


Right. I think you can still tell a simple story to beginners while supporting 
thin arrow or (this, ...) = {} for legacy software.

But I’d hope that the old code can be cleanly separated and that a new coding 
style will be supported by static checking tools such as JSLint.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Aymeric Vitte

1- Yes, several time that you mention it, and ++ from me each time

2- I prefer the dot notation rather than Object.extend, even if both are 
good


Le 28/04/2012 20:49, Kevin Smith a écrit :

Hi Angus!

1) Kevin et al suggested YAGN call/apply on (non-method)
functions. Here's a pretty neat example where call/apply is a
perfect fit for standalone functions - and would break if replaced
with fat arrows.

https://gist.github.com/2520731


This is a great example.  Two points:

1.)  In this case, I think it's going to be pretty difficult to prove 
that a dynamic this arrow function would be any more readable or 
better than current syntax:


// On what basis is this:
this.initialize = () - { ... };

// any better than this?
this.initialize = function() { ... };

There are a couple of characters saved, but it's less readable.  Why 
introduce new syntax for such dubious gain?


2.) For mixin stuff like your example, I think the elegant solution is 
object literal extension syntax:


https://gist.github.com/2521128

I'm not sure of the status of that syntax, but hopefully it will get 
included in ES6.


kevin


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


--
jCore
Email :  avi...@jcore.fr
Web :www.jcore.fr
Webble : www.webble.it
Extract Widget Mobile : www.extractwidget.com
BlimpMe! : www.blimpme.com

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich
If so then there is no need for any isArrowFunction or 
isFunctionThatBindsOrIgnoresThis predicate.


/be

Axel Rauschmayer wrote:
With “rules”, I don’t mean rules in the sense of the language spec, 
but rather rules for teaching the language to newcomers.

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich

Angus Croll wrote:

On Apr 29, 2012, at 1:28, Brendan Eichbren...@mozilla.org  wrote:


Axel Rauschmayer wrote:

I am not saying that the transition from the old rules to the new rules will be 
entirely painless, but if the new rules are simple, that pain is worth it, IMHO.

There are no new rules. Some functions ignore |this| or bind it rather than 
using it. These differences in kind do not change due to arrows.


Is there lexical |this| binding in ES5?


The only relevant issue for my exchange with Axel was whether any kind 
of this-binding exists in ES5 or older. The answer is yes.


Lexical this is often wanted and of course simulated with var self = 
this; ... function (){...self...} or .bind (implementable in pure ES3). 
But the lexical part doesn't enter into the contract of the API taking 
the function argument. It's between the API caller and the function 
argument's implementation -- when the latter is a closure in the former, 
lexical |this| often wins.


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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich

Brendan Eich wrote:
But the lexical part doesn't enter into the contract of the API taking 
the function argument. It's between the API caller and the function 
argument's implementation -- when the latter is a closure in the 
former, lexical |this| often wins. 


What does enter into the contract of the API taking the function 
argument is whether |this| is dynamically bound and passed with the 
expectation that the funarg not use some other |this|. But even then, 
the funarg is free to ignore |this|.


Between lexical-this and no-this, Kevin's analysis shows 80-90% (high 
end helped by method definition shorthand) coverage.


Thinking about arrows as a new thing to teach is fine, but we should not 
teach myths. |this| binding in JS today requires careful thought in all 
the usual scenarios: constructor, method, callback, global or local 
function. You can see why some advocate no-this uber alles!


But lexical-this is (if memory serves) around 40-50% gross of the 80-90% 
Kevin studied. That's big and we know people get that wrong.


If there's a strong use-case for - as function shorthand, we should 
consider adding - too. But the use-cases don't look strong enough yet, 
at least not to me (and I'm sympathetic!) to go back to TC39 asking for 
- on top of =.


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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Angus Croll
Then I guess we need another survey.

What does the JS arrow function proposal mean to you?
a) An abbreviated function syntax
b) A hard bound lexical |this| binding
c) Nothing

I'd gladly be proved wrong but my guess is most JS developers who don't
answer (c) will answer (a). (I see plenty of supporting evidence on
Twitter). Thin arrow would be an excellent decoy for those who expect (or
want) just (a).

This is also in response to Kevin's suggestion that arrow syntax is barely
more concise than regular function syntax. I don't think that's the
perception in the wider dev community, neither is it mine (in the best case
we save four ways - no function keyword, no braces, no argument parens, no
return stmt).

Personally I expect I can get by using function keyword where using = will
break my idioms - but its a bit much to expect everyone to understand and
react to these subtleties. I guess I'm trying to anticipate future cowpaths
and pave them before they make too much mess.


On Sun, Apr 29, 2012 at 11:37 AM, Brendan Eich bren...@mozilla.org wrote:

 Brendan Eich wrote:

 But the lexical part doesn't enter into the contract of the API taking
 the function argument. It's between the API caller and the function
 argument's implementation -- when the latter is a closure in the former,
 lexical |this| often wins.


 What does enter into the contract of the API taking the function argument
 is whether |this| is dynamically bound and passed with the expectation that
 the funarg not use some other |this|. But even then, the funarg is free to
 ignore |this|.

 Between lexical-this and no-this, Kevin's analysis shows 80-90% (high end
 helped by method definition shorthand) coverage.

 Thinking about arrows as a new thing to teach is fine, but we should not
 teach myths. |this| binding in JS today requires careful thought in all the
 usual scenarios: constructor, method, callback, global or local function.
 You can see why some advocate no-this uber alles!

 But lexical-this is (if memory serves) around 40-50% gross of the 80-90%
 Kevin studied. That's big and we know people get that wrong.

 If there's a strong use-case for - as function shorthand, we should
 consider adding - too. But the use-cases don't look strong enough yet, at
 least not to me (and I'm sympathetic!) to go back to TC39 asking for - on
 top of =.

 /be

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Axel Rauschmayer
Use case: error checks. For example: forEach could complain if it got both an 
arrow function and a thisValue. One could also complain if one expected a 
function with dynamic/unbound `this` and got a function with bound `this`, 
instead. To be extra strict, one could even complain when an unbound function 
is provided where a non-method function is expected (because either an arrow 
function should be used or a method’s `this` should be bound). All of these are 
things that you do as an API implementer, not necessarily as an API user.

Static checking would be even better, but then we would need a way to declare 
whether an argument is expected to have dynamic or lexical this.

Possibly 

On Apr 29, 2012, at 20:01 , Brendan Eich wrote:

 If so then there is no need for any isArrowFunction or 
 isFunctionThatBindsOrIgnoresThis predicate.
 
 /be
 
 Axel Rauschmayer wrote:
 With “rules”, I don’t mean rules in the sense of the language spec, but 
 rather rules for teaching the language to newcomers.
 

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich

Angus Croll wrote:

Then I guess we need another survey.


What was the first survey?

Kevin's analysis was on code, using a tool to classify functions as 
no-this/lexical-this vs. the rest.



What does the JS arrow function proposal mean to you?
a) An abbreviated function syntax
b) A hard bound lexical |this| binding
c) Nothing


This is all subjective and (without implementations to user-test) 
prospective. A survey is not going to be helpful IMHO. Rorschach test...


I'd gladly be proved wrong but my guess is most JS developers who 
don't answer (c) will answer (a). (I see plenty of supporting evidence 
on Twitter). Thin arrow would be an excellent decoy for those who 
expect (or want) just (a).


What do you mean by decoy?

This is all kind of twitter-ific, and so pretty much useless.

This is also in response to Kevin's suggestion that arrow syntaxis 
barely more concise than regular function syntax. I don't think that's 
the perception in the wider dev community, neither is it mine (in the 
best case we save four ways - no function keyword, no braces, no 
argument parens, no return stmt).

You mean where Kevin wrote:


// On what basis is this:
this.initialize = () - { ... };

// any better than this?
this.initialize = function() { ... };

There are a couple of characters saved, but it's less readable.  Why 
introduce new syntax for such dubious gain?



with a space before the - and one before { in both alternatives, and 
with the parameter list costing the same no matter what, there are five 
characters saved (' -' vs. 'function').


Five is good, I like it (I like thin arrows and proposed them along with 
fat arrows initially). But if this use-case is rare enough due to = and 
method definition shorthand (combined with Object.extend or better where 
possible), it may not be worth the added cost of -.


What's the cost of adding -? Mainly users having to remember when to 
use which, and getting it wrong. That's not a trivial concern, and it 
kept - out of consensus at the last TC39 meeting.


Personally I expect I can get by using function keyword where using = 
will break my idioms - but its a bit much to expect everyone to 
understand and react to these subtleties. I guess I'm trying to 
anticipate future cowpaths and pave them before they make too much mess.


Doing nothing leaves the cows falling off the wrong-this cliff. Doing 
something means adding syntax, there's no way to make a breaking change. 
Adding two things instead of one makes not only two things, but the 
problem of choice.


We may get - yet, don't get me wrong. But it won't come from surveys or 
twitter samples.


/be

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-29 Thread Brendan Eich

Axel Rauschmayer wrote:
Use case: error checks. For example: forEach could complain if it got 
both an arrow function and a thisValue.


Do you mean error, or warning?

Because you can use forEach with a function that ignores its |this|, and 
pass the thisValue optional parameter too, without error today. I see no 
good coming from trying to add an arrow-only error in the future when 
this case is not an error.


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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Angus Croll
I'm sorry that I could not reply to the multiple replies I got last
weekend. Simply can't get the time - plus I have a phobia of fan-out
replies (an issue with mail-based discussion groups?)

In any case here's a potted reply that addresses at least some of the
points:

1) Kevin et al suggested YAGN call/apply on (non-method) functions. Here's
a pretty neat example where call/apply is a perfect fit for standalone
functions - and would break if replaced with fat arrows.

https://gist.github.com/2520731

It's a simplified version of a a localStorage function (itself a mixin BTW)
which defines standard encoding methods and then mixes in whatever storage
technique is available to the browser. (An added bonus of having functions
here, aside from privacy, is that we can employ hoisting to move the
implementation nitty-gritty to the bottom, so as not to obscure the core
process)

2) Brendan et al pointed out that we already have hard |this| binding in
the form of Function::bind.

Yes, but bind is so blatantly explicit in its intention, the probability of
surprise is almost certainly less than with arrow functions, whose hard
lexical binding will surely come as a surprising side effect to many.

3) Several people suggested that there is a strong desire for a more
intuitive form of |this| binding.

Yes, people get confused by this binding; even though it is not hard to
learn the rules, and I know them very well, I still trip over them
sometimes. But unless we are going to introduce a hella strict mode that
reverts all previous rules of |this| binding, yet another rule will just
add to the morass.

Most of the yay, fat arrow comments I've seen from the dev community are
celebrating its brevity, I expect many of the authors have zero knowledge
of the lexical binding implications (why would they, unless they came from
CoffeeScript?). Now matter how much we justify fat arrow behavior as part
of  a long term vision, to many it is going to be a hidden, and unwanted
side effect.

At least introduce thin arrow at the same time, as a carrot to lure who
just want (and just expect) an abbreviated function syntax.

On Mon, Apr 23, 2012 at 3:01 PM, Brendan Eich bren...@mozilla.org wrote:

 Brendan Eich wrote:

 No, in any such prototype-getter-makes-bound-**function scenario, we
 would need memoization, so that

  o.m === o.m

 (Edit: I see you mention this below.)


 The real problem is better captured by showing the prototype p and two
 instances, o and q:

   p.m === p.m

 should be true. So should

  o.m === o.m

 and

  q.m === q.m

 but what about

  o.m === p.m

 and

  o.m === q.m

 JS requires distinct bound function identity from the unbound p.m
 identity, so false and false.

 If we managed to extend JS with a classy declarative syntax that enabled
 vtables, while keeping functions first class (at the price of
 prototype-chain mutation: assignment to override, or shadow; also of course
 delete), then we might well want true and true. But there would be no way
 in JS itself to implement such magic in terms of properties (data or
 accessor, doesn't matter) with function values.

 This is why I continue to think that we won't see what Alex predicted:
 prototype getter method vending. We haven't see it much in the wild yet
 either.

 /be

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Kevin Smith
Hi Angus!

1) Kevin et al suggested YAGN call/apply on (non-method) functions. Here's
 a pretty neat example where call/apply is a perfect fit for standalone
 functions - and would break if replaced with fat arrows.

 https://gist.github.com/2520731


This is a great example.  Two points:

1.)  In this case, I think it's going to be pretty difficult to prove that
a dynamic this arrow function would be any more readable or better than
current syntax:

// On what basis is this:
this.initialize = () - { ... };

// any better than this?
this.initialize = function() { ... };

There are a couple of characters saved, but it's less readable.  Why
introduce new syntax for such dubious gain?

2.) For mixin stuff like your example, I think the elegant solution is
object literal extension syntax:

https://gist.github.com/2521128

I'm not sure of the status of that syntax, but hopefully it will get
included in ES6.

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Brendan Eich

Kevin Smith wrote:
2.) For mixin stuff like your example, I think the elegant solution is 
object literal extension syntax:


https://gist.github.com/2521128

I'm not sure of the status of that syntax, but hopefully it will get 
included in ES6.


What if the ES6 solution were a standardized Object.extend, instead?

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Kevin Smith

 What if the ES6 solution were a standardized Object.extend, instead?


https://gist.github.com/2523106

(Assuming the same semantics...)

It's a little more wordy but still looks pretty good to me for this use
case.

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Tab Atkins Jr.
On Sat, Apr 28, 2012 at 11:13 AM, Angus Croll anguscr...@gmail.com wrote:
 1) Kevin et al suggested YAGN call/apply on (non-method) functions. Here's a
 pretty neat example where call/apply is a perfect fit for standalone
 functions - and would break if replaced with fat arrows.

 https://gist.github.com/2520731

 It's a simplified version of a a localStorage function (itself a mixin BTW)
 which defines standard encoding methods and then mixes in whatever storage
 technique is available to the browser. (An added bonus of having functions
 here, aside from privacy, is that we can employ hoisting to move the
 implementation nitty-gritty to the bottom, so as not to obscure the core
 process)

This is a mixin, which means that it needs methods, not functions.
Fat arrows aren't meant for methods.

This should rightly use 'function' (which is meant for methods), or
eventually use a mixin syntax.  (We should keep this in mind as an
example of mixins, so we don't accidentally forbid the ability to
choose which mixin to use dynamically, like this does.)

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Brendan Eich

Tab Atkins Jr. wrote:

This should rightly use 'function' (which is meant for methods), or
eventually use a mixin syntax.


See the version Kevin did using Object.extend and method definition 
shorthand:


https://gist.github.com/2523106

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Axel Rauschmayer
The following two rules should be everything one has to know regarding callable 
entities, in ES.next:
1. Method: `this` is an implicit parameter = use a method definition.
2. Non-method function: `this` is not an implicit parameter = use an arrow 
function.

In this light, I’d rewrite Kevin’s code slightly, because, conceptually, 
`localStorage ` is a non-method function:
  const localStorage = (obj) = {

Object.extend(obj, {
I think Angus’ most important point is this:

 Yes, people get confused by this binding; even though it is not hard to learn 
 the rules, and I know them very well, I still trip over them sometimes. But 
 unless we are going to introduce a hella strict mode that reverts all 
 previous rules of |this| binding, yet another rule will just add to the 
 morass.

It would be my hope that we can replace all previous rules with the two rules 
above. `apply` will mostly be replaced by the spread operator, `call` will 
mostly be replaced by calling a value. Some code such as `forEach` 
implementations that previously needed to use `call` to simulate lexical 
scoping don’t need a `thisValue` parameter for array functions.

Then the question remains: What else is possibly confusing? Using function* as 
a name for generators might be problematic.

 Most of the yay, fat arrow comments I've seen from the dev community are 
 celebrating its brevity, I expect many of the authors have zero knowledge of 
 the lexical binding implications (why would they, unless they came from 
 CoffeeScript?). Now matter how much we justify fat arrow behavior as part of  
 a long term vision, to many it is going to be a hidden, and unwanted side 
 effect.

True. I would ague that partitioning callable entities into the two categories 
mentioned at the beginning is natural and will allow you to forget about 
binding rules.

I am not saying that the transition from the old rules to the new rules will be 
entirely painless, but if the new rules are simple, that pain is worth it, 
IMHO. Library code might need to go to extra lengths to help normal developers 
with the transition (error messages, different behavior, tool functions, etc.) 
and – to be explicit – might need a predicate such as `isArrowFunction` (which 
should only ever be used under the hood and thus would not increase confusion 
for library *users*).

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-28 Thread Axel Rauschmayer
Correction:

Some code such as `forEach` implementations that previously needed to use 
`call` to simulate lexical scoping don’t need the `thisValue` parameter for 
arrow [was: array] functions.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-24 Thread Tab Atkins Jr.
On Mon, Apr 23, 2012 at 3:36 PM, David Herman dher...@mozilla.com wrote:
 I'm much more sympathetic to the idea of having *two* shorter-function 
 syntaxes, one optimized for methods and one optimized for non-method 
 functions. I understand the concern about bloat, but to me it addresses the 
 reality of different contexts in programming, e.g.:

    a.map(x = x + 1)

 vs

    box = {
        _value: 0,
        get: () - this._value,
        set(v) { this._value = v }
    }

I don't understand this example.  What is set(v) {...}?  It's not a
setter, because it's not associated with a property name.  Assuming
you meant set value(v) {...}, why not just use an ordinary getter as
well?

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


Re: Arrow binding

2012-04-24 Thread Rick Waldron
On Tue, Apr 24, 2012 at 12:33 PM, Tab Atkins Jr. jackalm...@gmail.comwrote:

 On Mon, Apr 23, 2012 at 3:36 PM, David Herman dher...@mozilla.com wrote:
  I'm much more sympathetic to the idea of having *two* shorter-function
 syntaxes, one optimized for methods and one optimized for non-method
 functions. I understand the concern about bloat, but to me it addresses the
 reality of different contexts in programming, e.g.:
 
 a.map(x = x + 1)
 
  vs
 
 box = {
 _value: 0,
 get: () - this._value,
 set(v) { this._value = v }
 }

 I don't understand this example.  What is set(v) {...}?  It's not a
 setter, because it's not associated with a property name.  Assuming
 you meant set value(v) {...}, why not just use an ordinary getter as
 well?


When I read this, I assumed it was a reference to this:
http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_property_shorthands

Which would produce a method named set on box

 box.set(42)
 box.get()

42


The example is easily confused.

Hope that helps

Rick






 ~TJ
 ___
 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: Arrow binding

2012-04-24 Thread Axel Rauschmayer
Seems like a typo and Tab’s got it right. The advantage of a thin arrow (over a 
method definition) here is that you can do an implicit return and have slightly 
less to type. Given that method definitions don’t appear inside statements, I 
don’t see that as a problem.

AFAIK, an implicit return of the completion value of a method is out, because 
one might involuntary return wrong values (previously: undefined, now: 
completion value).

On Apr 24, 2012, at 18:51 , Rick Waldron wrote:

 
 
 On Tue, Apr 24, 2012 at 12:33 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 23, 2012 at 3:36 PM, David Herman dher...@mozilla.com wrote:
  I'm much more sympathetic to the idea of having *two* shorter-function 
  syntaxes, one optimized for methods and one optimized for non-method 
  functions. I understand the concern about bloat, but to me it addresses the 
  reality of different contexts in programming, e.g.:
 
 a.map(x = x + 1)
 
  vs
 
 box = {
 _value: 0,
 get: () - this._value,
 set(v) { this._value = v }
 }
 
 I don't understand this example.  What is set(v) {...}?  It's not a
 setter, because it's not associated with a property name.  Assuming
 you meant set value(v) {...}, why not just use an ordinary getter as
 well?
 
 When I read this, I assumed it was a reference to this: 
 http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_property_shorthands
 
 Which would produce a method named set on box
 
  box.set(42)
  box.get()
 
 42
 
 
 The example is easily confused. 
 
 Hope that helps
 
 Rick
 
 
 
  
 
 ~TJ
 ___
 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

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-24 Thread Tab Atkins Jr.
On Tue, Apr 24, 2012 at 9:51 AM, Rick Waldron waldron.r...@gmail.com wrote:
 When I read this, I assumed it was a reference to
 this: http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_property_shorthands

 Which would produce a method named set on box

 box.set(42)
 box.get()

 42


 The example is easily confused.

Ah, that makes sense.  Okay.

In that case, I don't see why one wouldn't just use the same syntax
for both methods:

let box = {
  _value: 0,
  get() { return this._value; },
  set(v) { this._value = v; }
};

There doesn't seem to be a need there for thin-arrow (dynamic this) functions.

(Edit: Oh, I see, leaning on the completion value of thin-arrow
functions here lets you shave a few characters off.  The readability
loss of mixing the two syntaxes doesn't seem worthwhile, though.)

In fact, we can enumerate the different situations functions can
appear, since they're all gaining nice syntax:

1. Method on a class - when we get max/min classes, these'll have a
nice syntax, and will have dynamic-this behavior, just what we want.
2. Method on an object literal - if we have the syntax extension
outlined above, you also get dynamic-this, which we want.
3. Method dynamically attached to an object - here we don't have
special syntax, so we'll still need to use the function keyword.
4. Non-method function - you don't want a dynamic this, you want to
lexically close over all your variables.  Fat-arrows do this for you.
(The only reason to want dynamic this on a non-method is to do a
poor-man's currying.  Get a real curry function; this isn't worth the
bugs.)

The only case that isn't receiving special syntax (and thus which
could potentially benefit from a dynamic-this thin-arrow function) is
#3.  However, while #3 is common today, #1 and #2 will eat most of its
share.  I'm not sure that the remaining #3 cases will be worth a
special syntax.

If they are, though, nothing's closing the door on a thin-arrow in the
future.  No reason to block fat-arrow based on this.

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


Re: Arrow binding

2012-04-24 Thread Rick Waldron
On Tue, Apr 24, 2012 at 1:03 PM, Tab Atkins Jr. jackalm...@gmail.comwrote:

 On Tue, Apr 24, 2012 at 9:51 AM, Rick Waldron waldron.r...@gmail.com
 wrote:
  When I read this, I assumed it was a reference to
  this:
 http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_property_shorthands
 
  Which would produce a method named set on box
 
  box.set(42)
  box.get()
 
  42
 
 
  The example is easily confused.

 Ah, that makes sense.  Okay.

 In that case, I don't see why one wouldn't just use the same syntax
 for both methods:

 let box = {
  _value: 0,
  get() { return this._value; },
  set(v) { this._value = v; }
 };

 There doesn't seem to be a need there for thin-arrow (dynamic this)
 functions.


I think the colon was just a typo

Rick

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


Re: Arrow binding

2012-04-24 Thread Kevin Smith

 3. Method dynamically attached to an object - here we don't have
 special syntax, so we'll still need to use the function keyword.


Not necessarily.  Object literal extensions are a possibility here,
especially if you are attaching more than one method:

obj.{
addMethodA() { ... },
addMethodB() { ... }
};

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


Re: Arrow binding

2012-04-24 Thread Brendan Eich

Rick Waldron wrote:

I think the colon was just a typo


Dave is not cc'ed and may have missed the responses going back to Tab's 
first one, but I think there was no typo. Dave's example:


box = {
_value: 0,
get: () -  this._value,
set(v) { this._value = v }
}


Yes, it's awkward as examples go because get and set are contextual 
keywords, but this shows them used as plain identifiers. This also shows 
- as property value in an object literal (for property name 'get'), 
well as method definition shorthand (for 'set'), to contrast the two styles.


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


Re: Arrow binding

2012-04-24 Thread Brendan Eich

Tab Atkins Jr. wrote:

The only case that isn't receiving special syntax (and thus which
could potentially benefit from a dynamic-this thin-arrow function) is
#3.  However, while #3 is commontoday,  #1 and #2 will eat most of its
share.  I'm not sure that the remaining #3 cases will be worth a
special syntax.

If they are, though, nothing's closing the door on a thin-arrow in the
future.  No reason to block fat-arrow based on this.


Nicely put and I agree -- but I'm open to the future being sooner than 
we think. Getting = past TC39 took some doing, don't want to break 
consensus over pushing -. Do want to get to - if the use-cases from 
the field are strong enough.


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


Re: Arrow binding

2012-04-24 Thread Rick Waldron
On Tue, Apr 24, 2012 at 4:21 PM, Brendan Eich bren...@mozilla.org wrote:

 Rick Waldron wrote:

 I think the colon was just a typo


 Dave is not cc'ed and may have missed the responses going back to Tab's
 first one, but I think there was no typo. Dave's example:

box = {
_value: 0,
get: () -  this._value,
set(v) { this._value = v }
}


 Yes, it's awkward as examples go because get and set are contextual
 keywords, but this shows them used as plain identifiers. This also shows -
 as property value in an object literal (for property name 'get'), well as
 method definition shorthand (for 'set'), to contrast the two styles.


This makes complete sense now, thank you for the clarification.

Rick



  /be

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


Re: Arrow binding

2012-04-24 Thread David Herman
On Apr 24, 2012, at 9:51 AM, Rick Waldron wrote:

 On Tue, Apr 24, 2012 at 12:33 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 23, 2012 at 3:36 PM, David Herman dher...@mozilla.com wrote:
 
 box = {
 _value: 0,
 get: () - this._value,
 set(v) { this._value = v }
 }
 
 I don't understand this example.  What is set(v) {...}?  It's not a
 setter, because it's not associated with a property name.  Assuming
 you meant set value(v) {...}, why not just use an ordinary getter as
 well?
 
 When I read this, I assumed it was a reference to this: 
 http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_property_shorthands

Right. Thanks for providing the reference.

 Which would produce a method named set on box
 
  box.set(42)
  box.get()
 
 42
 
 The example is easily confused. 

Yeah, my bad. I was trying to demonstrate several syntaxes but shouldn't've 
picked an example with a method named set. To clarify the example:

box = {
_value: 0,
unbox: () - this._value,
setbox(v) { this._value = v }
}

Dave

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


Re: Arrow binding

2012-04-24 Thread David Herman
On Apr 24, 2012, at 10:03 AM, Tab Atkins Jr. wrote:

 There doesn't seem to be a need there for thin-arrow (dynamic this) functions.
 
 (Edit: Oh, I see, leaning on the completion value of thin-arrow
 functions here lets you shave a few characters off.  The readability
 loss of mixing the two syntaxes doesn't seem worthwhile, though.)

Lets you eliminate { and } and return, but requires additional : and 
-. Net savings of 3 characters. But more than that, eliminating return 
lets you write methods in a functional style without needing the explicit 
control flow operator.

 The only case that isn't receiving special syntax (and thus which
 could potentially benefit from a dynamic-this thin-arrow function) is
 #3.  However, while #3 is common today, #1 and #2 will eat most of its
 share.  I'm not sure that the remaining #3 cases will be worth a
 special syntax.

Classes certainly make it less necessary, given that cases like:

C.prototype.m1 = function(...) { ... };
C.prototype.m2 = function(...) { ... };
C.prototype.m3 = function(...) { ... };

will often be replaced by classes. But I am less sure it'll go away.

 If they are, though, nothing's closing the door on a thin-arrow in the
 future.  No reason to block fat-arrow based on this.

I'm definitely not advocating blocking fat-arrow! I favor both of them, though 
IMO fat-arrow is more important.

Dave

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


Re: Arrow binding

2012-04-24 Thread Allen Wirfs-Brock

On Apr 24, 2012, at 1:40 PM, David Herman wrote:

 On Apr 24, 2012, at 10:03 AM, Tab Atkins Jr. wrote:
 
 There doesn't seem to be a need there for thin-arrow (dynamic this) 
 functions.
 
 (Edit: Oh, I see, leaning on the completion value of thin-arrow
 functions here lets you shave a few characters off.  The readability
 loss of mixing the two syntaxes doesn't seem worthwhile, though.)
 
 Lets you eliminate { and } and return, but requires additional : and 
 -. Net savings of 3 characters. But more than that, eliminating return 
 lets you write methods in a functional style without needing the explicit 
 control flow operator.
 

I believe that we could grammatically use ArrowBody as the body of concise 
methods in object literals and classes.  In that case, Dave's example could be 
expressed as:

box = {
_value: 0,
unbox() ()- this._value,
setbox(v)  this._value = v 
}

It could also be used as the body of getter/setters

val = {
_value: 0,
get value() this._value,
set value(v)  this._value = v 
}



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


Re: Arrow binding

2012-04-24 Thread Axel Rauschmayer
 I believe that we could grammatically use ArrowBody as the body of concise 
 methods in object literals and classes.  In that case, Dave's example could 
 be expressed as:
 
 box = {
 _value: 0,
 unbox() ()- this._value,
 setbox(v)  this._value = v 
 }

That would be very nice. And it would be a perfect solution for the completion 
value issue: If you want to implicitly return the completion value, use an 
expression body.

Is there a typo in the code? I’d expect it to be:

box = {
_value: 0,
unbox() this._value,
setbox(v)  this._value = v
}

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-24 Thread Brendan Eich

Allen Wirfs-Brock wrote:

unbox() ()- this._value,


Left-over ()- in the middle, right?

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


Re: Arrow binding

2012-04-24 Thread David Herman
On Apr 24, 2012, at 2:09 PM, Allen Wirfs-Brock wrote:

 On Apr 24, 2012, at 1:40 PM, David Herman wrote:
 
 On Apr 24, 2012, at 10:03 AM, Tab Atkins Jr. wrote:
 
 There doesn't seem to be a need there for thin-arrow (dynamic this) 
 functions.
 
 (Edit: Oh, I see, leaning on the completion value of thin-arrow
 functions here lets you shave a few characters off.  The readability
 loss of mixing the two syntaxes doesn't seem worthwhile, though.)
 
 Lets you eliminate { and } and return, but requires additional : and 
 -. Net savings of 3 characters. But more than that, eliminating return 
 lets you write methods in a functional style without needing the explicit 
 control flow operator.
 
 
 I believe that we could grammatically use ArrowBody as the body of concise 
 methods in object literals and classes.  In that case, Dave's example could 
 be expressed as:
 
 box = {
 _value: 0,
 unbox() ()- this._value,

ITYM:

unbox() this._value,

 setbox(v)  this._value = v 
 }
 
 It could also be used as the body of getter/setters
 
 val = {
 _value: 0,
 get value() this._value,
 set value(v)  this._value = v 
 }

This all seems reasonable to me. I guess I see a couple reasonable alternatives 
here:

A. add thin arrow, add expression bodies to method shorthands

(-) Might be a bit much
(+) But all around a goodly set of convenience forms

B. add expression bodies to method shorthands, don't add skinny arrow

(-) Loses the flexibility of shorthand syntax for assigning to an existing 
object, a Tab pointed out. (Sorry Axel, mustache is not particularly 
Harmonious.)
(+) Keeps us to just one arrow form

C. eliminate method shorthands, add skinny arrow

(-) Loses the method shorthand in object literals
(-) Methods in classes would remain the same, which loses some symmetry 
between object literals and classes
(+) Eliminates visual confusion between getters/setters and method 
shorthand, but still with a minimal syntax (i.e., -)

All three of these options look pretty decent to me. I think I'd be pretty 
happy with any of them.

Dave

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


Re: Arrow binding

2012-04-24 Thread Allen Wirfs-Brock

On Apr 24, 2012, at 2:44 PM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
unbox() ()- this._value,
 
 Left-over ()- in the middle, right?

yes, that's right.  it should be
   unbox () this.value,

I was actually confusing that example with something
   
 thunk () () = this._value,

Allen


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


Re: Arrow binding

2012-04-24 Thread Axel Rauschmayer
 B. add expression bodies to method shorthands, don't add skinny arrow
 
 (-) Loses the flexibility of shorthand syntax for assigning to an 
 existing object, a Tab pointed out. (Sorry Axel, mustache is not particularly 
 Harmonious.)

Sorry to hear that. _.extend(), then (by whichever name)? As long as this 
operation can be performed in some manner...

 (+) Keeps us to just one arrow form
 
 C. eliminate method shorthands, add skinny arrow
 
 (-) Loses the method shorthand in object literals
 (-) Methods in classes would remain the same, which loses some symmetry 
 between object literals and classes
 (+) Eliminates visual confusion between getters/setters and method 
 shorthand, but still with a minimal syntax (i.e., -)

That would make super-references more difficult to implement, right? You’d have 
to invoke a defineMethod() somewhere along the way.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-24 Thread Allen Wirfs-Brock

On Apr 24, 2012, at 3:30 PM, Axel Rauschmayer wrote:

 B. add expression bodies to method shorthands, don't add skinny arrow
 
 (-) Loses the flexibility of shorthand syntax for assigning to an 
 existing object, a Tab pointed out. (Sorry Axel, mustache is not 
 particularly Harmonious.)
 
 Sorry to hear that. _.extend(), then (by whichever name)? As long as this 
 operation can be performed in some manner...

or we need to find mustached harmony, perhaps with some slight syntax change.  
The utility of .{ seems to be showing up fairly frequently in these discussions 
and also fits quite nicely with max-min classes for both instance and class 
property definition.

Allen



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


Re: Arrow binding

2012-04-24 Thread Axel Rauschmayer
Using a builtin function (as opposed to an operator) would be less problematic 
if one could invoke it infix, e.g.:

 this (extend) { x: x, y: y }

But I guess deciding on that will have to wait until operator overloading gets 
figured out.

On Apr 25, 2012, at 0:43 , Allen Wirfs-Brock wrote:

 
 On Apr 24, 2012, at 3:30 PM, Axel Rauschmayer wrote:
 
 B. add expression bodies to method shorthands, don't add skinny arrow
 
(-) Loses the flexibility of shorthand syntax for assigning to an 
 existing object, a Tab pointed out. (Sorry Axel, mustache is not 
 particularly Harmonious.)
 
 Sorry to hear that. _.extend(), then (by whichever name)? As long as this 
 operation can be performed in some manner...
 
 or we need to find mustached harmony, perhaps with some slight syntax change. 
  The utility of .{ seems to be showing up fairly frequently in these 
 discussions and also fits quite nicely with max-min classes for both instance 
 and class property definition.
 
 Allen
 
 
 
 

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-24 Thread Allen Wirfs-Brock

On Apr 24, 2012, at 3:53 PM, Axel Rauschmayer wrote:

 Using a builtin function (as opposed to an operator) would be less 
 problematic if one could invoke it infix, e.g.:
 
  this (extend) { x: x, y: y }

That wouldn't address the issues concerning cloning private names, super 
binding, etc.   I believe Dave's main issue is with the exact .{ syntax.  I'm 
flexible if that can be be harmoniously resolved with a minor syntactic change 
such as:

this.={methodA() {},
methodB() {}
};
 or 

this.+{methodA() {},
methodB() {}
};

or something else

this.{methodA() {},
methodB() {}
};

Allen

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


Re: Arrow binding

2012-04-24 Thread Kevin Smith
I wasn't convinced at first but I think the obj.{ ... } extension syntax
provides good utility.  I would strongly suggest not giving it up.  I've
used it in several refactoring examples on this list.

And I still don't see the attraction of thin arrow.  It provides no
semantic benefit and only very arguable syntactic benefit.  Object literal
methods and arrows eliminate the pain of function syntax for pretty much
every place where it is a pain.  The ability to eliminate return ... from
method bodies is a very dubious benefit; I believe that in the case of
methods this will make code less readable.

There seems to be a general assumption that arrows are the new function.
 This comes from CoffeeScript, I suppose, but in my opinion following that
route will neither make the language more readable nor expressive.

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


Arrow binding

2012-04-23 Thread Alex Russell
Despite making repeated arguments for soft binding, I'm pretty sure I haven't 
outlined here what it actually would *be*. Now that we're looking to add 
syntactic forms that create bound function objects (arrows and class methods), 
perhaps it's time to get consensus for or against. Soft binding has 2 
properties that make it desirable:

  * The global contract that methods can have their this re-set with .call() 
and .apply() is maintained
  * Common-case usage avoids the hazards of unbound and mis-appropriated this 
contexts. Most commonly, passing a method to a function which takes a callback:

 node.addEventListener(click, foo.bar);

The language today has 2 types of functions:

   * unbound: methods for which this is not fixed
   * hard-bound: methods bound by Function.prototype.bind()

Crucially, we have no syntax which creates hard-bound methods which means that 
they're not common (yet). To the extent that they are used, it is explicitly 
through forms like:

 node.addEventListener(click, foo.bar.bind(foo));

Or through libraries:

 dojo.connect(node, onclick, foo, bar);

This means that most users of most functions can still use .call() and .apply() 
without apprehension. Functions are still just functions.

The new forms we're adding (methods and arrows) have the potential to change 
this radically, causing a large percentage of functions encountered by 
programmers to have binding. If that binding is hard-binding, .call() and 
.apply() break in the minds of users. Perhaps that's fine by you, but in 
addition to being a contractual failure, it removes a form of genericness which 
is unique in the language.

What to do?

One option is to barrel onward with either unbound functions, hard bound 
functions, or some mix thereof. These are all painful in ways I don't need to 
spend time here explaining. I propose a third alternative: soft binding (aka 
preferred binding). It enables the following:

 node.addEventListener(click, foo.bar.prefer(foo));

While still allowing the following:

 foo.bar.call(otherThis, …args);

Functions with preferred bindings can still be re-bound either with new 
preferred binding or with new hard binding (both forms vend new functions 
objects and they do today).

Here's a JSFiddle with an a quick ES5 desugaring + example:

  http://jsfiddle.net/slightlyoff/739CS/20/

Note that we need to re-define .call() and .apply() to be savvy to preferences, 
but this doesn't seem particularly painful. I've bluntly worked around it in 
this example to avoid __proto__ re-wiring.

Thoughts?

--
Alex Russell
slightly...@google.com
slightly...@chromium.org
a...@dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

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


Re: Arrow binding

2012-04-23 Thread Kevin Smith
I'm not sure I understand the reasoning behind soft-binding.  If I use
arrow syntax, my intention is to close over |this|.  Allowing a caller to
change the binding of |this| will result in a violation of that closure.
 In this respect, |this| within an arrow function is no different that any
other closed-over variable.  I would not want a caller to be able to
override the binding on any of those variables, right?

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


Re: Arrow binding

2012-04-23 Thread Russell Leggett
On Mon, Apr 23, 2012 at 6:53 AM, Alex Russell a...@dojotoolkit.org wrote:

 Despite making repeated arguments for soft binding, I'm pretty sure I
 haven't outlined here what it actually would *be*. Now that we're looking
 to add syntactic forms that create bound function objects (arrows and class
 methods), perhaps it's time to get consensus for or against. Soft binding
 has 2 properties that make it desirable:

  * The global contract that methods can have their this re-set with
 .call() and .apply() is maintained
  * Common-case usage avoids the hazards of unbound and mis-appropriated
 this contexts. Most commonly, passing a method to a function which takes
 a callback:

 node.addEventListener(click, foo.bar);

 The language today has 2 types of functions:

   * unbound: methods for which this is not fixed
   * hard-bound: methods bound by Function.prototype.bind()

 Crucially, we have no syntax which creates hard-bound methods which means
 that they're not common (yet). To the extent that they are used, it is
 explicitly through forms like:

 node.addEventListener(click, foo.bar.bind(foo));

 Or through libraries:

 dojo.connect(node, onclick, foo, bar);

 This means that most users of most functions can still use .call() and
 .apply() without apprehension. Functions are still just functions.


That is only true for functions that actually use |this|. Even though bind
is probably not used in force yet because of cross-browser worries, var
self = this is used everywhere. Functions using that pattern are no more
usable with call/apply than arrow functions.



 The new forms we're adding (methods and arrows) have the potential to
 change this radically, causing a large percentage of functions encountered
 by programmers to have binding. If that binding is hard-binding, .call()
 and .apply() break in the minds of users. Perhaps that's fine by you, but
 in addition to being a contractual failure, it removes a form of
 genericness which is unique in the language.


Last I checked, the new method form is still a dynamic binding - otherwise
it wouldn't work. So really, you're just talking about arrow functions. In
the cases where arrow functions make the most sense (callbacks) you rarely
want a dynamic |this| - the oddball case being event handlers primarily.



 What to do?

 One option is to barrel onward with either unbound functions, hard bound
 functions, or some mix thereof. These are all painful in ways I don't need
 to spend time here explaining. I propose a third alternative: soft binding
 (aka preferred binding). It enables the following:

 node.addEventListener(click, foo.bar.prefer(foo));

 While still allowing the following:

 foo.bar.call(otherThis, …args);

 Functions with preferred bindings can still be re-bound either with new
 preferred binding or with new hard binding (both forms vend new functions
 objects and they do today).

 Here's a JSFiddle with an a quick ES5 desugaring + example:

  http://jsfiddle.net/slightlyoff/739CS/20/

 Note that we need to re-define .call() and .apply() to be savvy to
 preferences, but this doesn't seem particularly painful. I've bluntly
 worked around it in this example to avoid __proto__ re-wiring.

 Thoughts?


When I enumerate the use cases, I have trouble finding a *good* reason for
soft-binding. You are correct that it removes a certain amount of
genericness to use hard-binding, but I think writing a generic function
should be intentional.

function foo(bar){
bar.call(otherThis);
}

If you write a function foo that expects a function parameter bar, and you
intend to override it's this value, that is a contract, and the |this| you
substitute also needs to abide by the contract for use inside of the bar
function. Traditionally, this would be done using a *parameter* to bar,
instead of changing |this| which seems fragile at best. The only use case I
see for changing |this| is if the function bar passed in is already an
existing method.

//For this use case, why would I ever use an arrow function
foo( ()=this.myBar() );

//instead of just passing the method directly
foo( this.myBar );

I really just don't see the value of changing the |this| value of a
function created for the purpose of being an argument to a function. And
frankly, I just don't see many other use cases for arrows. Maybe thats the
part I'm missing.

- Russ



 --
 Alex Russell
 slightly...@google.com
 slightly...@chromium.org
 a...@dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

 ___
 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: Arrow binding

2012-04-23 Thread Alex Russell
On Mon, Apr 23, 2012 at 2:47 PM, Russell Leggett
russell.legg...@gmail.com wrote:


 On Mon, Apr 23, 2012 at 6:53 AM, Alex Russell a...@dojotoolkit.org wrote:

 Despite making repeated arguments for soft binding, I'm pretty sure I
 haven't outlined here what it actually would *be*. Now that we're looking to
 add syntactic forms that create bound function objects (arrows and class
 methods), perhaps it's time to get consensus for or against. Soft binding
 has 2 properties that make it desirable:

  * The global contract that methods can have their this re-set with
 .call() and .apply() is maintained
  * Common-case usage avoids the hazards of unbound and mis-appropriated
 this contexts. Most commonly, passing a method to a function which takes a
 callback:

     node.addEventListener(click, foo.bar);

 The language today has 2 types of functions:

   * unbound: methods for which this is not fixed
   * hard-bound: methods bound by Function.prototype.bind()

 Crucially, we have no syntax which creates hard-bound methods which means
 that they're not common (yet). To the extent that they are used, it is
 explicitly through forms like:

     node.addEventListener(click, foo.bar.bind(foo));

 Or through libraries:

     dojo.connect(node, onclick, foo, bar);

 This means that most users of most functions can still use .call() and
 .apply() without apprehension. Functions are still just functions.


 That is only true for functions that actually use |this|. Even though bind
 is probably not used in force yet because of cross-browser worries, var
 self = this is used everywhere. Functions using that pattern are no more
 usable with call/apply than arrow functions.

everywhere is incredibly strong wording, and I think that in the
large, you're probably not correct. Some large % of code might
manually call their scope through closure binding, but even that
isn't an argument against soft binding.

 The new forms we're adding (methods and arrows) have the potential to
 change this radically, causing a large percentage of functions encountered
 by programmers to have binding. If that binding is hard-binding, .call() and
 .apply() break in the minds of users. Perhaps that's fine by you, but in
 addition to being a contractual failure, it removes a form of genericness
 which is unique in the language.


 Last I checked, the new method form is still a dynamic binding - otherwise
 it wouldn't work. So really, you're just talking about arrow functions. In
 the cases where arrow functions make the most sense (callbacks) you rarely
 want a dynamic |this| - the oddball case being event handlers primarily.

Having done this dance a couple of times, let me suggest to you that
the method form will *eventually* end up at a per-class getter on the
prototype which vends an instance function which is bound. People will
(reasonably) want binding of some sort.

 What to do?

 One option is to barrel onward with either unbound functions, hard bound
 functions, or some mix thereof. These are all painful in ways I don't need
 to spend time here explaining. I propose a third alternative: soft binding
 (aka preferred binding). It enables the following:

     node.addEventListener(click, foo.bar.prefer(foo));

 While still allowing the following:

     foo.bar.call(otherThis, …args);

 Functions with preferred bindings can still be re-bound either with new
 preferred binding or with new hard binding (both forms vend new functions
 objects and they do today).

 Here's a JSFiddle with an a quick ES5 desugaring + example:

      http://jsfiddle.net/slightlyoff/739CS/20/

 Note that we need to re-define .call() and .apply() to be savvy to
 preferences, but this doesn't seem particularly painful. I've bluntly worked
 around it in this example to avoid __proto__ re-wiring.

 Thoughts?


 When I enumerate the use cases, I have trouble finding a *good* reason for
 soft-binding. You are correct that it removes a certain amount of
 genericness to use hard-binding, but I think writing a generic function
 should be intentional.

     function foo(bar){
         bar.call(otherThis);
     }

 If you write a function foo that expects a function parameter bar, and you
 intend to override it's this value, that is a contract, and the |this| you
 substitute also needs to abide by the contract for use inside of the bar
 function. Traditionally, this would be done using a *parameter* to bar,
 instead of changing |this| which seems fragile at best. The only use case I
 see for changing |this| is if the function bar passed in is already an
 existing method.

     //For this use case, why would I ever use an arrow function
     foo( ()=this.myBar() );

     //instead of just passing the method directly
     foo( this.myBar );

 I really just don't see the value of changing the |this| value of a function
 created for the purpose of being an argument to a function. And frankly, I
 just don't see many other use cases for arrows. Maybe thats the part I'm
 missing.


Re: Arrow binding

2012-04-23 Thread Kevin Smith

 Yeah, I think you're missing the composition arguments. If I create
 mixins with methods, they're going to have a promiscuious this as a
 *feature*. You might not write code like this today, but you probably
 should ;-)


But anyone who understands the language would not use arrow functions for
that use case.  I assume you're referring to something like this (Angus
posted a similar example a while back):

function mixin() {
this.{
addMethodA() {},
addMethodB() {}
};
}

Your idea of a preferred binding for methods is interesting (as a form of
method extraction), but I don't think it can be applied to arrow functions.

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


Re: Arrow binding

2012-04-23 Thread Mark S. Miller
On Mon, Apr 23, 2012 at 6:46 AM, Kevin Smith khs4...@gmail.com wrote:

 I'm not sure I understand the reasoning behind soft-binding.  If I use
 arrow syntax, my intention is to close over |this|.  Allowing a caller to
 change the binding of |this| will result in a violation of that closure.
  In this respect, |this| within an arrow function is no different that any
 other closed-over variable.  I would not want a caller to be able to
 override the binding on any of those variables, right?


Right. I think this is the key issue regarding defaults and what arrow
functions must do -- hard binding. Making this binding soft would destroy
the integrity of lexical capture that arrow functions provide for this.

Alex, http://wiki.ecmascript.org/doku.php?id=strawman:soft_bind, which we
worked on together, implements soft binding as a simple small library. We
wrote this over a year ago. Since then, I've never found a need for this.
Could you give a concrete example where this is useful? Do such uses
justify a role beyond such library implementations? I'm inclined to YAGNI
on this one.





 kevin

 ___
 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: Arrow binding

2012-04-23 Thread Axel Rauschmayer
On Apr 23, 2012, at 16:17 , Alex Russell wrote:

 Having done this dance a couple of times, let me suggest to you that
 the method form will *eventually* end up at a per-class getter on the
 prototype which vends an instance function which is bound. People will
 (reasonably) want binding of some sort.


An important use case. However, wouldn’t it be simpler to achieve the same goal 
by allowing the following two operations to co-exist?

- get: obj.method invokes the getter – which hard-binds on demand (but might 
cache via a weakmap).
- call: obj.method() invokes the actual method.

Hence, in addition to getters and setters, we would have callers. If a 
property doesn’t have a caller then obj.method() would first invoke the getter 
and then try to call the result.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Arrow binding

2012-04-23 Thread John J Barton
On Mon, Apr 23, 2012 at 3:53 AM, Alex Russell a...@dojotoolkit.org wrote:


 The new forms we're adding (methods and arrows) have the potential to
 change this radically, causing a large percentage of functions encountered
 by programmers to have binding. If that binding is hard-binding, .call()
 and .apply() break in the minds of users. Perhaps that's fine by you, but
 in addition to being a contractual failure, it removes a form of
 genericness which is unique in the language.


Sorry if I missed reading about this but: why can't we re-bind 'this in
bound functions when using call(), apply() ? I'm sure it will make more
work for JIT optimizers but they are very good and love this kind of
problem.

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


Re: Arrow binding

2012-04-23 Thread Alex Russell
The semantic of Function.prototype.bind() precludes it. If we could
relax that to be effectively soft-bound, I'm *completely* on board,
but I expect it will cause some problems.

We could, of course, try this out in Chrome and see how it goes.

On Mon, Apr 23, 2012 at 4:32 PM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Mon, Apr 23, 2012 at 3:53 AM, Alex Russell a...@dojotoolkit.org wrote:


 The new forms we're adding (methods and arrows) have the potential to
 change this radically, causing a large percentage of functions encountered
 by programmers to have binding. If that binding is hard-binding, .call() and
 .apply() break in the minds of users. Perhaps that's fine by you, but in
 addition to being a contractual failure, it removes a form of genericness
 which is unique in the language.


 Sorry if I missed reading about this but: why can't we re-bind 'this in
 bound functions when using call(), apply() ? I'm sure it will make more work
 for JIT optimizers but they are very good and love this kind of problem.

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


Re: Arrow binding

2012-04-23 Thread Oliver Hunt

On Apr 23, 2012, at 8:32 AM, John J Barton wrote:

 
 
 On Mon, Apr 23, 2012 at 3:53 AM, Alex Russell a...@dojotoolkit.org wrote:
 
 The new forms we're adding (methods and arrows) have the potential to change 
 this radically, causing a large percentage of functions encountered by 
 programmers to have binding. If that binding is hard-binding, .call() and 
 .apply() break in the minds of users. Perhaps that's fine by you, but in 
 addition to being a contractual failure, it removes a form of genericness 
 which is unique in the language.
 
 Sorry if I missed reading about this but: why can't we re-bind 'this in 
 bound functions when using call(), apply() ? I'm sure it will make more work 
 for JIT optimizers but they are very good and love this kind of problem.

Because the semantics would be difficult to implement -- jit or otherwise -- 
and difficult to specify otherwise :-(

The more serious issue though is that of program behaviour -- if a developer 
has strongly bound this, it is reasonable to expect that they had some reason 
to do so.  If you provide a mechanism that can bypass that binding you can 
break program abstraction, potentially allowing security bugs in the SES/Caja 
type language models.

It would also imply being able to rebind |this| in bound functions, which would 
be insane.

--Oliver

 
 jjb
 ___
 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: Arrow binding

2012-04-23 Thread Alex Russell
On Apr 23, 2012, at 3:30 PM, Russell Leggett wrote:

 
  That is only true for functions that actually use |this|. Even though bind
  is probably not used in force yet because of cross-browser worries, var
  self = this is used everywhere. Functions using that pattern are no more
  usable with call/apply than arrow functions.
 
 everywhere is incredibly strong wording, and I think that in the
 large, you're probably not correct. Some large % of code might
 manually call their scope through closure binding, but even that
 isn't an argument against soft binding.
 
 Let me reword from everywhere to extremely common. My point was that even 
 though it is not used in every case, it is used often enough that |this| 
 cannot be relied on. And my other point was that you have to know how the 
 function passed in *uses* this, which makes it pretty tightly coupled.
  
  Last I checked, the new method form is still a dynamic binding - otherwise
  it wouldn't work. So really, you're just talking about arrow functions. In
  the cases where arrow functions make the most sense (callbacks) you rarely
  want a dynamic |this| - the oddball case being event handlers primarily.
 
 Having done this dance a couple of times, let me suggest to you that
 the method form will *eventually* end up at a per-class getter on the
 prototype which vends an instance function which is bound. People will
 (reasonably) want binding of some sort.
 
 If that happens, then I will be more inclined to agree with you. Until that 
 happens, I guess I just don't. Your argument seems balanced on something 
 which you think will happen. I find that hard to agree with.
 
  
  I really just don't see the value of changing the |this| value of a function
  created for the purpose of being an argument to a function. And frankly, I
  just don't see many other use cases for arrows. Maybe thats the part I'm
  missing.
 
 Yeah, I think you're missing the composition arguments. If I create
 mixins with methods, they're going to have a promiscuious this as a
 *feature*. You might not write code like this today, but you probably
 should ;-)
 
 I use mixins all the time, I just don't see them being being declared with 
 arrow functions, which was the point I was trying to make here. If you are 
 creating a mixin, then you would most likely want to use the new method 
 syntax or at least the function syntax, but I think it would be silly to use 
 the arrow function syntax, so I guess I'm just not sympathetic to that.

If methods on classes sprout binding of some sort, this will be the natural 
style. And I think that's a good place to be. If both arrow and class methods 
lexically soft-bind, truly unbound functions will be declared as function and 
will be easy to spot.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Arrow binding

2012-04-23 Thread Brandon Benvie
The real use case that I constantly run into has nothing to do with binding
at all, rather the need for Function.prototype.partial and *no specific
binding*. The primary use case for soft binding or dynamic non-method
binding, as mentioned above, is the event callback and that's weird
semantic captured in the way the DOM works. The problem is that with JS
it's a prevalent use case because of how closely associated JS has been
with the DOM.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-23 Thread Allen Wirfs-Brock

On Apr 23, 2012, at 11:17 AM, Brendan Eich wrote:

 Apologies for sounding schizo. I'm saying prototypal wins at scale and I see 
 it more often used, but closure has its fans and it's used too.
 
 With both (plus other approaches such as Angus's) I do not think it's a given 
 that in the future, JS will make methods auto-bind |this| via prototypal 
 accessors. That is possible today (ES5 and earlier getter/setter support in 
 most browsers) and it's quite rare -- I can think of only a few cases, one of 
 which is in the new I18N library.

And note that the I18N usage is for a situation where the property is vending 
(to use Alex's term) a function that is intended to be used as a call-back that 
needs access to the state of the instance it was accessed from. In particular, 
it enables someone to say:

someArray.sort(myCollator.compare)
rather than
someArray.sort(myCollator.compare.bind(myCollator)

This seems like an important idiom hat may become even more important in the 
context of ES6.  We probably need to encourage broader education about this 
idiom.  But it isn't clear that it needs special syntax or even what that might 
be.

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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-23 Thread Brendan Eich

Allen Wirfs-Brock wrote:

This seems like an important idiomhat may  become even more important in the 
context of ES6.  We probably need to encourage broader education about this 
idiom.  But it isn't clear that it needs special syntax or even what that might 
be.


Dave wrote

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

for this and it's a live strawman (albeit in conflict with guard syntax, 
or perhaps just reusing it outside of binding contexts). Agree it's not 
ready for ES6, of course.


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


Re: Bound instance-function vending (was RE: Arrow binding)

2012-04-23 Thread Brendan Eich

Brendan Eich wrote:
No, in any such prototype-getter-makes-bound-function scenario, we 
would need memoization, so that


  o.m === o.m

(Edit: I see you mention this below.) 


The real problem is better captured by showing the prototype p and two 
instances, o and q:


   p.m === p.m

should be true. So should

  o.m === o.m

and

  q.m === q.m

but what about

  o.m === p.m

and

  o.m === q.m

JS requires distinct bound function identity from the unbound p.m 
identity, so false and false.


If we managed to extend JS with a classy declarative syntax that enabled 
vtables, while keeping functions first class (at the price of 
prototype-chain mutation: assignment to override, or shadow; also of 
course delete), then we might well want true and true. But there would 
be no way in JS itself to implement such magic in terms of properties 
(data or accessor, doesn't matter) with function values.


This is why I continue to think that we won't see what Alex predicted: 
prototype getter method vending. We haven't see it much in the wild yet 
either.


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


Re: Arrow binding

2012-04-23 Thread David Herman
On Apr 23, 2012, at 3:53 AM, Alex Russell wrote:

 This means that most users of most functions can still use .call() and 
 .apply() without apprehension. Functions are still just functions.

You're assuming your conclusion: that there's some sort of platonic ideal 
(just functions) of JS functions always having a use for their `this` 
binding. But when I pass function() { elt.style.background = 'yellow' } to 
setTimeout, is my function some betrayal of The JavaScript Way? No it's a 
function that changes the background color of an element. It's not evil. It's 
every bit as valid a function as one that's intended to be a method.

JavaScript uses functions for many different things: constructors, top-level 
functions, callbacks, and methods. Sometimes you need all their features, 
sometimes you don't.

 The new forms we're adding (methods and arrows) have the potential to change 
 this radically, causing a large percentage of functions encountered by 
 programmers to have binding. If that binding is hard-binding, .call() and 
 .apply() break in the minds of users. Perhaps that's fine by you, but in 
 addition to being a contractual failure, it removes a form of genericness 
 which is unique in the language.

I don't accept this frame. The contract of .call() and .apply() is that their 
first argument specifies the binding for `this`. The contract between a 
function and its caller is that the caller provides bindings for the arguments, 
and the callee decides what to do with those arguments. It is perfectly 
acceptable for the callee to disregard some arguments.

Now, it's certainly possible to make functions less abstract than necessary by 
using closed-over variables instead of arguments (including `this`). Maybe 
where I'm closer to agreement with you is that *when you're implementing 
methods* it's better to use `this` than to lexically close over the object the 
methods were created for. But not all functions in JavaScript are methods.

I'm much more sympathetic to the idea of having *two* shorter-function 
syntaxes, one optimized for methods and one optimized for non-method functions. 
I understand the concern about bloat, but to me it addresses the reality of 
different contexts in programming, e.g.:

a.map(x = x + 1)

vs

box = {
_value: 0,
get: () - this._value,
set(v) { this._value = v }
}

 One option is to barrel onward with either unbound functions, hard bound 
 functions, or some mix thereof. These are all painful in ways I don't need to 
 spend time here explaining.

Maybe you do need to, because I'm not convinced. JavaScript already lets you do 
either. With the shorter function syntax, we've only been discussing 
conveniences for things you can already express. You claim that conveniences 
like fat arrow are radical, but soft bind is the proposal that breaks an 
existing language guarantee. It introduces a new distinction: a callee can now 
change behavior depending on whether it was called via f() or vs f.call(null). 
That breaks the feature that you can always use .call/.apply as a drop-in 
replacement for the equivalent explicit call.

Dave

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