Easier to read lambdas

# Igor Bukanov (18 years ago)

Consider the following es3 examples involving simple and more complex lamdas:

array.sort(function(a, b) { return a - b; });

array.sort(function(a, b) { if (typeof a != "number" || typeof b != "number") throw "Unexpected type of array element"; return a - b; });

setTimeout(function() { if (someCondition) reportTimeout(); }, 1000);

This not only looks ugly due to that }); but IMO hard to read since it is not immediately obvious where the lambda parameter ends especially in the third example.

In es4 the first one can be written using function shortcut as:

array.sort(function(a, b) a - b);

But such shorter form is not available for multi-statement lambdas so the second and third examples will continue to look ugly and be hard to read (again IMO).

To mitigate this I suggest to allow to move the definition of the body of lambda used inside an expression statement to the end of the statement. This would make possible to write:

array.sort(function(a, b)) a - b;

array.sort(function(a, b)) { if (typeof a != "number" || typeof b != "number") throw "Unexpected type of array element"; return a - b; }

setTimeout(function(), 1000) { if (someCondition) reportTimeout(); }

Here is more examples:

Upper-case the array:

var upper = array.map(function(elem)) elem.toUpperCase();

Do complex SQL transaction:

function doSomethingWithNewPeople() { let selectSQL ="SELECT code, name from people where status='new'"; let insertSQL = "INSERT INTO young(name,age) values (?,?)"; connection.transaction(function(tx)) { connection.prepare(function(selectStatement), selectSQL) { connection.prepare(function(insertStatement), insertSQL) { selectStatement.executeQuery(function(name, age)) { if (name.match(/.*Joe/) && age % 2) insertStatement.execute(name, age); } } } } }

In fact such notation competes with using generators for enumeratons. Compare:

for (let [index, elem] in array) print("["+index+"]="+elem);

with

array.forEach(function(elem, index)) print("["+index+"]="+elem);

So how does it look for you?

, Igor

# Jeff Dyer (18 years ago)

I have to admit that this is a quite unintuitive transformation for me. How would bodies of multiple lambda arguments be expressed? If as a comma separated list, then you have the list within a list problem again.

Anyway, separating the head of a lambda from the body is hard for me to read. But perhaps that is because I'm just not used to it.

# Magnus Kristiansen (18 years ago)

On Tue, 29 May 2007 16:18:06 +0200, Igor Bukanov <igor at mir2.org> wrote:

To mitigate this I suggest to allow to move the definition of the body of lambda used inside an expression statement to the end of the statement. This would make possible to write:

array.sort(function(a, b)) a - b;

array.sort(function(a, b)) { if (typeof a != "number" || typeof b != "number") throw "Unexpected type of array element"; return a - b; }

setTimeout(function(), 1000) { if (someCondition) reportTimeout(); }

When you're putting the function code outside the statement, it becomes a
hybrid of using a non-anonymous function and using a lambda. The above
sorter is not very different from this (apart from being anonymous):

array.sort(comp); function comp(a, b) { if (typeof a != "number" || typeof b != "number") throw "Unexpected type of array element"; return a - b; }

Here is more examples:

Upper-case the array:

var upper = array.map(function(elem)) elem.toUpperCase();

Do complex SQL transaction:

function doSomethingWithNewPeople() { let selectSQL ="SELECT code, name from people where status='new'"; let insertSQL = "INSERT INTO young(name,age) values (?,?)"; connection.transaction(function(tx)) { connection.prepare(function(selectStatement), selectSQL) { connection.prepare(function(insertStatement), insertSQL) { selectStatement.executeQuery(function(name, age)) { if (name.match(/.*Joe/) && age % 2) insertStatement.execute(name, age); } } } } }

This example, in my opinion, shows how the hybrid approach becomes less
legible than either alternative. With regular lambdas, you can use
whitespace to separate out the structure of subfunctions. With normal
functions, they're naturally separated. The hybrid cascade above really
doesn't make sense to me, especially considering cases with multiple
lambdas in the same function as Jeff Dyer mentioned.

# Jason Orendorff (18 years ago)

On 5/29/07, Igor Bukanov <igor at mir2.org> wrote:

In fact such notation competes with using generators for enumeratons. Compare:

Competing notations are not necessarily a good thing.

So how does it look for you?

It looks superficially like Ruby blocks. But Ruby's syntax is more nicely sugared, and more importantly, Ruby's other language features are designed to work smoothly with blocks. "break" and "return" do the right thing inside Ruby blocks. Ruby has a different flavor of "yield" that complements blocks. And so on. None of this support is there in ES4.