To be fair, after a long reflection, I have been concluding that no other 
proposal beat {|| ...} for block lambda at this time. Also, I’ve found some use 
cases where block-lambda are actually useful (something I was really curious 
about before thinking about it). In the future, they may even be used a lot by 
transpilers to emulate new language constructs in a ES-friendly way.

The main point I dislike with the current proposal is that it makes 
block-lambda used at places where I think they should not. It’s not because 
they are useful to solve some problems they are useful to fix all. Most of the 
time, when we want a lambda, we don’t want TCP. We want a new function. Just 
and only that. Since we want a new function, we are requesting function-like 
semantics. It’s logical.

An exemple:

    function A() {
     let ret = {|x| return x; };
     let inc = {|x| x+1 };
     let j = 0;
     while (true) {
      if (j > 3) ret(j);
      j = inc(j); 
     }
    }

I don’t think “inc” should be a block-lambda. It can be, if someone do that, I 
would not bother modifying the code. But it’s not the natural way to think. 
What we need here is not an “extension” of the current function (which is a 
block lambda is), we need a new function.

The problem is that the current syntax is too long :

    let inc = function(x) { return x+1; }

I think (but I don’t say it’s what should be done, it’s up to debate) that 
alongside block-lambda, we should introduce a ‘canonical’ lambda proposal, that 
would just be syntaxic sugar for plain old functions.

The syntax I propose would be:

    ‘@(‘ + <argument-list> + ‘)’ + <statement>;

     // or if too complex
    ‘@(‘ + <argument-list> + ‘)’ + ‘{‘ + <statement> + ‘}’;

That would desugar to:

    (function lambda_lineX_colY_fileZ(<argument-list>) {
        return do {
            <statement>
        };
    }).bind(this);

That would allow the following samples :

    let inc = @(x) x+1;

    array.map(@(x) x+1);

    array.map(@(x) { 
        if(x.hasKey(‘a’)) {
            x.get(‘a’) 
        } else {
            undefined 
                }
    });

and the more complex ones :

    array.map(@(x) {

        while(x.parentNode) { 
            
            x=x.parentNode; 
            if(x.tagName==’DIV’) { return x; } 
            
        }

        console.log(‘An element that has no parent DIV has been found.’);
        return undefined;

    });

Please note that the last one seems very complex to write using a block-lambda :

    array.map({|x| let returnValue;

        while(x.parentNode) {
            
            x=x.parentNode;
            if(x.tagName==’DIV’) { returnValue=x; break; }
            
        }

        if(returnValue) {
            returnValue;
        } else {
            console.log(‘An element that has no parent DIV has been found.’);
            undefined;
        }

    });

That proposal does offer some middle ground between 

- ‘functions’ (classical functions)
- ‘lambdas’ which are local functions that are not meant to go outside the 
scope of an action
- ‘block-lambdas’ which are internal functions that are not meant to go outside 
the scope of a function scope.

Anyone can use what’s the most convenient for him, I think there’s room for all 
those things.
François

From: Axel Rauschmayer 
Sent: Wednesday, January 18, 2012 8:48 PM
To: Oliver Hunt 
Cc: Brendan Eich ; es-discuss Steen 
Subject: Re: Block lambda is cool, its syntax isn't
Maybe the problem here is that I don't like the block-lambda concept itself.


I’m curious: What do you dislike?

-- 
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
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to