Block lambda is cool, its syntax isn't

François REMY fremycompany_pub at yahoo.fr
Sat Jan 21 01:39:33 PST 2012


This seems pretty easy to enforce to me.

function a(x) {

    let count = 0;
    [
        (x+1)^(x-1),
        (x*x),
        (2*x-1)
    ];

    arr.forEach({|x|
        if((x&1)==0) count++;
    });

    return count;
}




-----Message d'origine----- 
From: Brendan Eich
Sent: Saturday, January 21, 2012 2:08 AM
To: François REMY
Cc: es-discuss
Subject: Re: Block lambda is cool, its syntax isn't

Rust is a static language with many guarantees. It's not really
comparable to JS here.

JS extended with block-lambdas has no way to force downward-funarg-only
contract on functions called with block-lambda arguments. And indeed,
nothing goes wrong if those block-lambdas escape via the heap and are
called after the enclosing function's activation, which passed the
block-lambda down, has returned. Only if the block-lambda does a control
effect that would propagate to the enclosing function's activation is
there a dynamic error.

JS is a dynamic language. When you write "it should only be allowed",
are you seriously proposing a checkable syntax and static check of some
kind? How would that work?

(Aside: I wish I had used "fn" instead of "function" in 1995!)

/be

> François REMY <mailto:fremycompany_pub at yahoo.fr>
> January 20, 2012 1:38 PM
> Just to add weight to my previous mail, you may find it interesting to 
> notice that my proposed syntax match nearly exactly the proposed syntax of 
> the new Mozilla-editored Rust programming language: 
> http://doc.rust-lang.org/doc/tutorial.html#closure-compatibility
>
>    call_twice({|| "I am a stack closure; });
>
>    call_twice(fn@() { "I am a boxed closure"; });
>
> It confirms my feeling about {|| ...}: it should only be allowed in a 
> context where the function still exists; it's a way to return the control 
> back to the calling function when you need to call a "callback-able" 
> function for some reason. At every other place, you should use 'normal' 
> closures (the language-agnostic equivalent of ECMAScript functions), for 
> which we should have a simplified syntax (aka syntaxic sugar). I don't 
> bother if it has to start by @, #, %, µ, § or anyting else, but I feel 
> strongly about the fact we need it.
>
> Now, I think everyone got my point, I leave the final discussion to group 
> members. But, at least, my message was sent. ;-)
>
> Best regards,
> François
>
> François REMY <mailto:fremycompany_pub at yahoo.fr>
> January 19, 2012 12:19 PM
> It may be just a personnal taste, but I've to agree the current proposal 
> (#() ...) seems very appealing to me. I did not respond to your mail 
> proposing to use the Arrow syntax because it seems obscure to me. The 
> distinction between "normal" and "fat" arrow is thin, does not make sense. 
> You either need a function-object (which doesn't have 'this' mapping, has 
> expandos) or a local-function (which has 'this' mapping, just need to be a 
> [Call] target). If you need the first, you need a traditionnal function 
> since you need something not-frozen that can be added to objects as a 
> property at a later time. If you want 'this' mapping, you need something 
> that only makes sense in a local context.
>
> Additionnaly, the arrow syntax is illogical. You usually say "I want a 
> function of (X,Y) which returns X+Y" or "I want to transform X in 
> X.toString", not "From X, I want to get X.toString()".
>
> Freezing a local function seems as acceptable to me as it seemed to 
> others. A LF should only be used in a controlled context where the 
> function itself is just used as a function, not an object. But if it's not 
> acceptable to other members, I'm not against a @(x) syntax that does not 
> offer frozen functions (but I think it's a missed optimization 
> opportunity). The point about Conditionnal Compiling in IE is not valid 
> anymore since Microsoft has deleted HTML Conditionnal Comments because 
> they were not standards (even if they were used a lot), so I don't think 
> the obscure and fewly used JScript CC are meant to stay, especially if it 
> hurts another proposal.
>
> In my view of the thing, a local function should be used as a function in 
> the mathematical sense of the term: you give a parameter, it returns its 
> image by the function.
>
> The cases we are trying to solve:
>
>    var inc=#(x) x+1;
>
>    array.map(#(x) x.toString());
>
>    array.filter(#(x) isValid(x));
>
>    array.map(#(x) {
>        while(x.previousSibling) x=x.previousSibling;
>        return x;
>    });
>
> For example, I don't see this as a good use-case of a LocalFunction :
>
>    ...
>    refreshLayout: function(e) {
>        ...
>        requestAnimationFrame(#(e) this.refreshLayout(e));
>    }
>    ...
>
> It should be a block lambda instead, because it's meant to 'continue' the 
> current function in a sort of async while(true) loop.
>
>    ...
>    refreshLayout: function(e) {
>        ...
>        requestAnimationFrame({|e| this.refreshLayout(e) });
>    }
>    ...
>
> For all of the use cases where a "mathematical function" is requied, you 
> just need some valid [Call]-able item. You will never add expandos on an 
> function you don't know (ie that you received as a parameter). You'll wrap 
> it before, if you really need that. If you want the full flexibility of a 
> function-as-an-object, it means you need a 'true function'; LF are not 
> meant to replace functions in the long run, they are made to serve the 
> case where you want a short, action-related, contextual function. That 
> means 'this' binding, if needed, just like it's in languages like dotNET.
>
> However, I would like to hear more about the specific reasons that led Arv 
> and Alex think a LF should not be frozen.
>
> Regards,
> François
>
>
>
> PS: The synax I speak about for LocalFunctions would be:
>
> <LocalFunctionExpression>:
>    '#(' <argument-list> ')' <expression>
>    or
>    '#(' <argument-list> ') {' <statements>* '}'
>
> They would be 'bound-this' if there's a 'this' in their body, but can be 
> left unbounded if there's no since it has no visible effet. If they don't 
> reference variables of a scope, they should not use reference scope and 
> may be reused accross function calls.
>
>
>
>
> -----Message d'origine----- From: Brendan Eich
> Sent: Thursday, January 19, 2012 8:27 PM
> To: Axel Rauschmayer ; Andreas Rossberg
> Cc: François REMY ; Oliver Hunt ; es-discuss Steen
> Subject: Re: Block lambda is cool, its syntax isn't
>
> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 19, 2012 9:31 AM
>
> Rationale: wouldn’t freezing by default be OK for 98% of the cases? If
> you want anything else, you can use a traditional function. Then the
> above syntax as the only function shorthand would be OK.
>
>
> First, #(params) { body } was proposed by Arv and Alex:
>
> http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax
>
> Arv and Alex feel strongly that the shorter function syntax (anything
> shortening 'function' syntax) must not freeze by default.
>
> There was lack of clarity about whether completion value as implicit
> return value was part of the proposal. If so, controvery, since there is
> a completion value leak hazard. TC39 seems to agree the solution there
> is something with different look & feel, such as block-lambdas.
>
> But, making a one-char grawlix shorthand for 'function' while still
> requiring 'return' is not considered enough of a shorthand. A possible
> cure here is to support an alternative body syntax: #(params) expr.
> However, this inverts precedence if done naively. It also runs into
> trouble trying to prefer an object literal over a block statement. I've
> worked on both of these in the context of
>
> http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax
>
> This superseded shorter_function_syntax, but ran into grammatical issues
> that have vexed it.
>
> But notice that throughout this, no one advancing a proposal advocated
> freezing by default. JS developers use function objects as mutable
> objects. Not just to set .prototype, also to decorate with ad-hoc and
> meta-data properties. Freezing is not wanted by default.
>
> I agree that for block-lambdas it's easier to say "freeze by default".
> For merely "shorter function syntax", no. Functions are mutable objects
> by default in JS. This matters for minifiers, which may not be able to
> see all the mutations but would love to use shorter syntax for
> 'function' syntax, blindly.
>
> /be
>
> Brendan Eich <mailto:brendan at mozilla.com>
> January 19, 2012 11:27 AM
> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 19, 2012 9:31 AM
>
> Rationale: wouldn’t freezing by default be OK for 98% of the cases? If you 
> want anything else, you can use a traditional function. Then the above 
> syntax as the only function shorthand would be OK.
>
>
> First, #(params) { body } was proposed by Arv and Alex:
>
> http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax
>
> Arv and Alex feel strongly that the shorter function syntax (anything 
> shortening 'function' syntax) must not freeze by default.
>
> There was lack of clarity about whether completion value as implicit 
> return value was part of the proposal. If so, controvery, since there is a 
> completion value leak hazard. TC39 seems to agree the solution there is 
> something with different look & feel, such as block-lambdas.
>
> But, making a one-char grawlix shorthand for 'function' while still 
> requiring 'return' is not considered enough of a shorthand. A possible 
> cure here is to support an alternative body syntax: #(params) expr. 
> However, this inverts precedence if done naively. It also runs into 
> trouble trying to prefer an object literal over a block statement. I've 
> worked on both of these in the context of
>
> http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax
>
> This superseded shorter_function_syntax, but ran into grammatical issues 
> that have vexed it.
>
> But notice that throughout this, no one advancing a proposal advocated 
> freezing by default. JS developers use function objects as mutable 
> objects. Not just to set .prototype, also to decorate with ad-hoc and 
> meta-data properties. Freezing is not wanted by default.
>
> I agree that for block-lambdas it's easier to say "freeze by default". For 
> merely "shorter function syntax", no. Functions are mutable objects by 
> default in JS. This matters for minifiers, which may not be able to see 
> all the mutations but would love to use shorter syntax for 'function' 
> syntax, blindly.
>
> /be
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Axel Rauschmayer <mailto:axel at rauschma.de>
> January 19, 2012 9:31 AM
>
> Rationale: wouldn’t freezing by default be OK for 98% of the cases? If you 
> want anything else, you can use a traditional function. Then the above 
> syntax as the only function shorthand would be OK.
>
> -- 
> Dr. Axel Rauschmayer
> axel at rauschma.de <mailto:axel at rauschma.de>
>
> home: rauschma.de <http://rauschma.de>
> twitter: twitter.com/rauschma <http://twitter.com/rauschma>
> blog: 2ality.com <http://2ality.com>
>
> Brendan Eich <mailto:brendan at mozilla.com>
> January 19, 2012 9:25 AM
>
> I'm not sure what you mean. I proposed this a while ago ("Harmony of My 
> Dreams") but we don't want frozen by design, and without the # the result 
> is ambiguous without restricted productions, and hazardous on that 
> account.
>
> The idea that any grawlixy preifx will do is false. Hash is wanted for 
> consistent freeze/seal prefixing. Arrow is better and putting it at the 
> front solves the grammar problems with arrow function syntax as current 
> drafted.
>
> /be
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 



More information about the es-discuss mailing list