On what we consider to be beautiful lambda expressions...
On Monday, 2011-05-09 at 10:02 , François REMY wrote:
We’ve seen many proposals and arguments in the current thread about the arrow syntax. While it’s great to start with a brainstorm, the discussion should be, at some time, recentered on how to write beautiful lambda expressions. The objective of the “short” function syntax [if it once gets implemented] would be to have a nicer way to write lambdas (keeping that in mind during the discussion is important because, for the other uses, the classical “function” syntax will still be applicable).
I think shorter function syntax is a goal which is not limited to lambdas only.
We all know we have our own prefered syntax based on our tastes and our experience with other languages. While the fact that the ECMAScript comitee can’t choose something that will make everybody happy, it should at least try to evaluate the pro and cons of all possibilities (rejecting a proposal because it use a symbol that may be used in the Private Name proposal seems to me a little weird, since we also could use another symbol or name in the Private Name proposal and/or in the new function notation proposal).
Evaluating the best proposal should be done by :
identifying use cases of lambdas
seeing what’s the current patterns used at this time to solve those uses cases
in ES today (and in libraries like jQuery, Prototype.js, ...)
in other programming languages (seems to have been done in large part by the precedent mails)
seeing how to improve those use cases (and if it’s needed)
considering what’s the best solution from three point of view :
Compiler (ease of parsing)
IDE (ease of implementation)
Developer (readability / writability)
Maybe some people in the comitee are already performing that work, so I’ll not attempt to go more in depht into this.
To make some progress on the subject, here’s a little summary of the available proposals, at this time :
// CSharp-like syntax array.filter((x) –> x.isEmpty);
// MatLAB-like syntax array.filter(@(x) x.isEmpty); array.filter(#(x) x.isEmpty);
// VB-like syntax array.filter(function(x) x.isEmpty); array.filter(function(x) { return x.isEmtpy; })
Other proposals were the following (but I suspect the syntax is problematic) :
// Ruby-like syntax (?) array.filter({|x| x.isEmpty}); array.filter((x){x.isEmpty);
I don’t know if it’s derisable, but we could do even shorter (and readable) by making the assumption that if no argument list is provided, then the lamda takes only one named argument (that could be called “a”, considering that no good developer would use this single letter as variable names outside lambdas). This would allow the following additionnals :
array.filter(->a.isEmpty);
array.filter(@a.isEmpty); array.filter(#a.isEmpty);
array.filter(function a.isEmpty);
As I already previously said, I kinda like the @-proposal [[ array.filter(@a.isEmpty); ]] because it’s very short to write, it’s easy to understand, very similar to the current syntax (an important point that the arrow syntax completely miss) and can be acustomated to more complex cases like [[
array.filter(@(childArray,childIndex) { for(var i=0; i<childArray.length; i++) { if(i%2==0 && a[i]<=0) return false; } return true; });
]]
Something to be pointed out is that in the case of more complex functions, the most readable way is often to create a “true” fuction and use its name as the filter argument [[
var isValid = @(childArray,childIndex) { for(var i=0; i<childArray.length; i++) { if(i%2==0 && a[i]<=0) return false; } return true; };
array.filter(isValid);
]]
Another fact used in the discussion is that the arrow proposal provides a way to ‘bind’ a lambda to an element. Sorry, I’m not sure about why this is useful to have two kind of lambdas. A lambda is, most of the time, a function that’s independant of the place where’s it is written, used to perform a simple test. The most common use of ‘bind’ is to send an object’ function as a callback to an asynchronous code (event, ....). In this case, you’ll not create a lambda because the original function already exists [[ el.onclick=this.removeFromParent.bind(this) vs el.onclick=()=>this.removeFromParent() ]].
I think your assumption that short function syntax is only for lambdas is false. Also here is some real world examples of self = this pattern that is solved by =>
www.google.com/codesearch?hl=en&lr=&q=self\s*%3D\sthis%3B\sfunction+lang%3Ajavascript+case%3Ayes&sbtn=Search www.google.com/codesearch?hl=en&lr=&q=.bind(this+lang%3Ajavascript+case%3Ayes&sbtn=Search
We’ve seen many proposals and arguments in the current thread about the arrow syntax. While it’s great to start with a brainstorm, the discussion should be, at some time, recentered on how to write beautiful lambda expressions. The objective of the “short” function syntax [if it once gets implemented] would be to have a nicer way to write lambdas (keeping that in mind during the discussion is important because, for the other uses, the classical “function” syntax will still be applicable).
We all know we have our own prefered syntax based on our tastes and our experience with other languages. While the fact that the ECMAScript comitee can’t choose something that will make everybody happy, it should at least try to evaluate the pro and cons of all possibilities (rejecting a proposal because it use a symbol that may be used in the Private Name proposal seems to me a little weird, since we also could use another symbol or name in the Private Name proposal and/or in the new function notation proposal).
Evaluating the best proposal should be done by :
identifying use cases of lambdas
seeing what’s the current patterns used at this time to solve those uses cases
seeing how to improve those use cases (and if it’s needed)
considering what’s the best solution from three point of view :
Maybe some people in the comitee are already performing that work, so I’ll not attempt to go more in depht into this.
To make some progress on the subject, here’s a little summary of the available proposals, at this time :
Other proposals were the following (but I suspect the syntax is problematic) :
I don’t know if it’s derisable, but we could do even shorter (and readable) by making the assumption that if no argument list is provided, then the lamda takes only one named argument (that could be called “a”, considering that no good developer would use this single letter as variable names outside lambdas). This would allow the following additionnals :
As I already previously said, I kinda like the @-proposal [[ array.filter(@a.isEmpty); ]] because it’s very short to write, it’s easy to understand, very similar to the current syntax (an important point that the arrow syntax completely miss) and can be acustomated to more complex cases like [[
]]
Something to be pointed out is that in the case of more complex functions, the most readable way is often to create a “true” fuction and use its name as the filter argument [[
]]
Another fact used in the discussion is that the arrow proposal provides a way to ‘bind’ a lambda to an element. Sorry, I’m not sure about why this is useful to have two kind of lambdas. A lambda is, most of the time, a function that’s independant of the place where’s it is written, used to perform a simple test. The most common use of ‘bind’ is to send an object’ function as a callback to an asynchronous code (event, ....). In this case, you’ll not create a lambda because the original function already exists [[ el.onclick=this.removeFromParent.bind(this) vs el.onclick=()=>this.removeFromParent() ]].
It’s however possible to say that @-function (aka lambdas) are automatically bound to the current “this”, if needed. It would allow things like [[ array.filter(@this.isValidChild(a)); ]] to work seamlessy. It would also makes a clear distinction between the @ syntax and the “function” syntax, that could justify that both coexists (someone’ else complain was about having two syntax to do the same thing).
This would lead to [[ el.onclick=this.removeFromParent.bind(this) vs [email protected]() ]]
Hoping this mail can help the comitee members to move forward, François