Yep, it's also quite a good explanation. Dmitry.
On Sun, Jan 2, 2011 at 5:32 PM, fernando trasvina <[email protected]>wrote: > > On Jan 1, 2011, at 5:00 AM, Dmitry A. Soshnikov wrote: > > On 01.01.2011 2:43, fernando trasvina wrote: > > Hi. very nice explanation but what i don't fully understand is why the > grouping operator makes the parenthesis following the function declaration > work as call. > > > (function(x){alert(x)}(1)); > > > why this is not treated the same way as: > > > function(x){}(1); > > > > Because inside the grouping operator () there can be only an _expression_. > No matter in which way you place a function there (with a call or without > it) -- it's treated as FE (function expression). I.e. everything that is > placed inside the grouping operator is an expression. > > (1); // grouping operator with expression 1 > ("test"); // with expression "test" > (function () {}); // with a functional expression > > So in case when you have the following construction: > > (function (x) {alert(x)})(1); > > We have: > > 1. A grouping operator with a function(al) expression inside. It's exactly > the sign to the interpreter that this _something inside the grouping > operator_ should be _evaluated_ during the _execution_. I.e. we have a > function definition there. And this function definition is provided during > the runtime. > > 2. Applying (1) on the result of which is returned by the grouping operator > (i.e. our just created function). And notice, this is already exactly the > _call_ -- (1), but not a grouping operator as it was with a function > declaration (FD). > > Since FDs are created on entering the context stage (i.e. before the > runtime execution), obviously the following (1) _cannot_ be treated as a > _call_. Therefore, the parser considers theses as two constructions: FD and > a the following grouping operator: > > function foo(x){alert(x)}(1); // not a call, but syntactically correct > > > Backing to FEs. When you have the following construction: > > (function (x) {alert(x)}(1)); > > Again it's the sign to the interpreter that _something_ inside the grouping > operator should happen (evaluated) at runtime. And what is inside it doesn't > matter much at the stage of the parsing. When at runtime the interpreter > reaches this line, it just eval(uate)s the expression -- were the expression > is again -- creating the function and calling it. > > > Nice. thx. i read a lil bit after reading this and i think the explanation > could be improved by including the following areas (not in this particular > form but this helped me on clearing doubts): > > Program: > Statement > FunctionDeclaration > > Statement: > Block > VariableStatement > EmptyStatement > ExpressionStatement > IfStatement > IterationStatement > ContinueStatement > BreakStatement > ReturnStatement > WithStatement > LabelledStatement > SwitchStatement > ThrowStatement > TryStatement > DebuggerStatement > > FunctionDeclaration : > function Identifier ( FormalParameterListopt ) { FunctionBody } > > FunctionExpression : > function Identifieropt ( FormalParameterListopt ) { FunctionBody } > > notice the optional clause on Identifier for the FunctionExpression, > FunctionDeclaration requires Identifier > > ExpressionStatement : > [lookahead ∉ {{, function}] Expression ; > > Expression: (there are too many but you can see them in appendix 3 of > ECMA-262, FunctionExpression is not directly listed but you can see it on > Appendix 5 of ECMA-262) > > Note: This excludes Block and FunctionExpression > > So with this rules at the program level and every place where StatementList > is used you will always get a FunctionDeclaration. > > FunctionDeclarations are never callable, this is the rule for a > CallExpression > > CallExpression : > MemberExpression Arguments > CallExpression Arguments > CallExpression [ Expression ] > CallExpression . IdentifierName > > A FunctionDeclaration is not a MemberExpression neither a CallExpression. > Statement is a not returning construct in the language, it does not "return" > anything so no CallExpression can be formed. > > note that GroupingOperator is a PrimaryExpression not a Statement so it > does "returns" something. > > you say this already but maybe give it more importance. > > GroupingOperator > PrimaryExpression: > ... > (Expression) > > This means that everything inside () is treated as an expression and when > you put function x(){} inside its parsed as FunctionExpression never as > FunctionDeclaration > > hope it helps, it helped me to understand it better. > > > Also i would like to give credit and recommend the way Jose Antonio Perez > wrote the explanation > > > Happy new year ;) > > >> Remember, a A FunctionDeclaration's function is added to the >> VariableEnvironment in Variable Instantiation. It is not and cannot be an >> ExpressionStatement. >> >> An FunctionExpression is an ExpressionStatement; it is not bound to the VE >> (VariableEnvironment) on entering an execution context. A FunctionExpression >> is disabiguated from a FunctionDeclaration by the fact that an >> ExpressionStatement can't start with the `function` keyword. >> > > >> When `f` is called, a VariableEnvironment (VE) is created. For each >> FunctionDeclaration in the FunctionBody of `f` the Identifier of that >> FD is added to the VE. >> > > The point that Dmitry is trying to explain has nothing to do with the > running, is a topic within the field of parsing. The grammar that you can > see in specification is equivalent to > > *SourceElements*: ( Statement | *FunctionDeclaration* )+ > > *Program*: SourceElements? > > *FunctionBody*: SourceElements? > > *FunctionDeclaration* : function Identifier > (FormalParameterList?){FunctionBody*}* > > > The source will be divided into *Statements* and *FunctionDeclarations*, > and a FunctionDeclaration ends in a "*}*", therefore the arguments of a > hypothetical call haven't connection with "their function", the parser will > place they in the following SourceElement, an ExpressionStatement. > > i just copied his post here. > > > Lastly. > > I would like to call everyone to not give answers like because its a Syntax > Error, or Because that is not allowed. > please explain as necessary so people interested on the topic get all the > relevant information they want (need) if you don't want too well just don't > say anything but misleading explanations or getting defensive over a mistake > like a typo or focusing on irrelevant details will not lead us anywhere and > people will not come to this list to read another fight. > > This is of everyone, i got into a pointless discussion here too and i hope > i never get into one again, please lets focus on improving the community. > > > > > Notice though, that there is one subtle case related with these two similar > forms. > > // first function > var foo = function () { > return true; > } > > // second function > (function (x) {return x})(1); > > > Here the trick is just seeing this as the parser does. > > var foo = FunctionExpression Arguments Arguments > > var foo = CallExpression Arguments > > var foo = CallExpression > > so at the end you can rewrite the code as the following. > > var foo = function () { return true }(function (x) {return x})(1); > > Boolean is not callable. > > same as: (true)(1); > > > The example above has an error (try to explain why). Thus, the following > example doesn't: > > // first function > var foo = function () { > return true; > } > > // second function > (function (x) {return x}(1)); > > > var foo = FunctionExpression Arguments > > Arguments is an ArgumentsList with a single Argument, the result of > (FunctionExpression Arguments) > > FunctionExpression Arguments is a CallExpression > > in this case returns 1; > > so at the end you can rewrite the code as the following. > > var foo = function () { return true }(1); > > > Also, try to explain why. Though, the topic of the answer isn't related > with the discussed topic. How the answer will change if the `foo` function > will return an object of the other kind? > > > return a Function instance because its the only callable object. > > there is another way to "fix" it. just finish the statement after asigning > foo. > > // first function > var foo = function () { > return true; > }; // <-- here > > // second function > (function (x) {return x})(1); > > Maybe this examples should also be included on your article as possible > gotchas. > > > Dmitry. > > On Dec 31, 2010, at 7:46 AM, Dmitry A. Soshnikov wrote: > > > Just for those who don't use Twitter. I've just edited my > "ES3.Ch5.Functions" article in respect of explanation the "surrounding > parentheses". The thing is, that almost _all_ explanations (in books, > articles, etc) were at least very incomplete (and even wrong). > > > So, why does this code produces a SyntaxError: > > > function () { > > ... > > }() > > > // or with name > > > function foo() { > > ... > > }(); > > > Try to provide as much complete explanation as possible. Also try to answer > without cheating ;) The correct and full explanation is here: > http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses > > > Dmitry. > > > P.S.: Happy New Year! > > > -- > > To view archived discussions from the original JSMentors Mailman list: > http://www.mail-archive.com/[email protected]/ > > > To search via a non-Google archive, visit here: > http://www.mail-archive.com/[email protected]/ > > > To unsubscribe from this group, send email to > > [email protected] > > > -- > To view archived discussions from the original JSMentors Mailman list: > http://www.mail-archive.com/[email protected]/ > > To search via a non-Google archive, visit here: > http://www.mail-archive.com/[email protected]/ > > To unsubscribe from this group, send email to > [email protected] > > > -- > To view archived discussions from the original JSMentors Mailman list: > http://www.mail-archive.com/[email protected]/ > > To search via a non-Google archive, visit here: > http://www.mail-archive.com/[email protected]/ > > To unsubscribe from this group, send email to > [email protected]<jsmentors%[email protected]> > -- To view archived discussions from the original JSMentors Mailman list: http://www.mail-archive.com/[email protected]/ To search via a non-Google archive, visit here: http://www.mail-archive.com/[email protected]/ To unsubscribe from this group, send email to [email protected]
