François REMY <mailto:fremycompany_...@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_...@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:a...@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:bren...@mozilla.com>
January 19, 2012 11:27 AM
Axel Rauschmayer <mailto:a...@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@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
Axel Rauschmayer <mailto:a...@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
a...@rauschma.de <mailto:a...@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:bren...@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@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss