Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #27546 > unrolled thread

! function

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2015-05-07 20:15 +1000
Last post2015-05-08 12:08 +0200
Articles 19 — 8 participants

Back to article view | Back to comp.lang.javascript


Contents

  ! function Andrew Poulos <ap_prog@hotmail.com> - 2015-05-07 20:15 +1000
    Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-07 13:04 +0200
    Re: ! function "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2015-05-07 05:02 -0700
    Re: ! function Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-05-07 12:27 -0300
      Re: ! function JJ <jj4public@vfemail.net> - 2015-05-08 00:09 +0700
      Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-07 21:07 +0200
        Re: ! function "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-05-07 21:31 +0200
          Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-07 22:20 +0200
            Re: ! function "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-05-07 23:27 +0200
              Re: ! function "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-05-08 00:26 +0200
                Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-08 11:00 +0200
                  Re: ! function James Lewis <lewisje@gmail.com> - 2015-06-05 09:10 -0700
            Re: ! function Scott Sauyet <scott.sauyet@gmail.com> - 2015-05-18 13:31 -0700
              Re: ! function "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-05-19 01:39 +0200
                Re: ! function Scott Sauyet <scott.sauyet@gmail.com> - 2015-05-19 05:48 -0700
          Re: ! function Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-05-07 17:47 -0300
            Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-07 23:22 +0200
              Re: ! function Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-05-07 19:08 -0300
                Re: ! function "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2015-05-08 12:08 +0200

#27546 — ! function

FromAndrew Poulos <ap_prog@hotmail.com>
Date2015-05-07 20:15 +1000
Subject! function
Message-ID<ddSdncub_tOuptbInZ2dnUVZ8gidnZ2d@westnet.com.au>
I was looking at some "swipe" libraries when I happened upon hammer.js.
<http://hammerjs.github.io/dist/hammer.min.js>

I've no idea yet as to its quality but the very first line begins with

! function(a, b, c, d) {

What's the reason behind starting with an exclamation mark?

Andrew Poulos

[toc] | [next] | [standalone]


#27547

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-07 13:04 +0200
Message-ID<XnsA49384F0298ADeejj99@194.109.133.246>
In reply to#27546
Andrew Poulos <ap_prog@hotmail.com> wrote on 07 mei 2015 in 
comp.lang.javascript:

> I was looking at some "swipe" libraries when I happened upon hammer.js.
> <http://hammerjs.github.io/dist/hammer.min.js>
> 
> I've no idea yet as to its quality but the very first line begins with
> 
>! function(a, b, c, d) {
> 
> What's the reason behind starting with an exclamation mark?

!function(a,b,c,d){"use strict";[..

..]}(window,document,"Hammer");

Google is your friend!

The unary operator ! (as do ~, -, +) allows the parameters in the () at the 
end to invoke the function in-place and hides the function name from the 
global, and any other [only outside?] scope/namespace.

<http://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-
do-before-the-function>

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#27548

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2015-05-07 05:02 -0700
Message-ID<9ec8009b-5d09-4b74-9738-85ee91718d4c@googlegroups.com>
In reply to#27546
On Thursday, May 7, 2015 at 5:15:23 AM UTC-5, Andrew Poulos wrote:
> I was looking at some "swipe" libraries when I happened upon hammer.js.
> <http://hammerjs.github.io/dist/hammer.min.js>
> 
> I've no idea yet as to its quality but the very first line begins with
> 
> ! function(a, b, c, d) {
> 
> What's the reason behind starting with an exclamation mark?

It's a recent trend to replace (function(){...})(); you could use other operators as well

[toc] | [prev] | [next] | [standalone]


#27553

FromJoao Rodrigues <groups_jr-1@yahoo.com.br>
Date2015-05-07 12:27 -0300
Message-ID<mig09m$not$1@speranza.aioe.org>
In reply to#27546
On 07/05/2015 07:15, Andrew Poulos wrote:
> I was looking at some "swipe" libraries when I happened upon hammer.js.
> <http://hammerjs.github.io/dist/hammer.min.js>
> 
> I've no idea yet as to its quality but the very first line begins with
> 
> ! function(a, b, c, d) {
> 
> What's the reason behind starting with an exclamation mark?


An Immediately-Invoked Function Expression (IIFE) is usually written as:
(function() { /* etc. */ })();

Or:

(function() { /* etc. */ }()); // Douglas Crockford's preference.

But we can use unary operators instead of the wrapping parentheses too,
if we don't care about the return value of the IIFE:

+function() { /*...*/ }();
!function() { /*...*/ }();
-function() { /*...*/ }();
~function() { /*...*/ }();

Even the void operator can be used:
void function () { /*...*/ }();

-- 
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#27554

FromJJ <jj4public@vfemail.net>
Date2015-05-08 00:09 +0700
Message-ID<11hznrmj1c5dy.797kyp37lr5d.dlg@40tude.net>
In reply to#27553
On Thu, 07 May 2015 12:27:55 -0300, Joao Rodrigues wrote:
> 
> An Immediately-Invoked Function Expression (IIFE) is usually written as:
> (function() { /* etc. */ })();
> 
> Or:
> 
> (function() { /* etc. */ }()); // Douglas Crockford's preference.
> 
> But we can use unary operators instead of the wrapping parentheses too,
> if we don't care about the return value of the IIFE:
> 
> +function() { /*...*/ }();
> !function() { /*...*/ }();
> -function() { /*...*/ }();
> ~function() { /*...*/ }();
> 
> Even the void operator can be used:
> void function () { /*...*/ }();

With unary operators, it will make the JavaScript engine evaluate the
function return value using that operator. In theory, this will add more
processing time although it's very tiny.

With (), e.g. (function(){})(), there's no additional processing time.

But what about when using void? e.g. void function(){}()
If I understand it correctly, the function return value won't be evaluated,
but it does add additional code which replace the final expression with
undefined.

[toc] | [prev] | [next] | [standalone]


#27555

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-07 21:07 +0200
Message-ID<XnsA493D6D7F9E67eejj99@194.109.133.246>
In reply to#27553
Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
comp.lang.javascript:

> On 07/05/2015 07:15, Andrew Poulos wrote:
>> I was looking at some "swipe" libraries when I happened upon hammer.js.
>> <http://hammerjs.github.io/dist/hammer.min.js>
>> 
>> I've no idea yet as to its quality but the very first line begins with
>> 
>> ! function(a, b, c, d) {
>> 
>> What's the reason behind starting with an exclamation mark?
> 
> 
> An Immediately-Invoked Function Expression (IIFE) is usually written as:
> (function() { /* etc. */ })();
> 
> Or:
> 
> (function() { /* etc. */ }()); // Douglas Crockford's preference.
> 
> But we can use unary operators instead of the wrapping parentheses too,
> if we don't care about the return value of the IIFE:
> 
> +function() { /*...*/ }();
>!function() { /*...*/ }();
> -function() { /*...*/ }();
> ~function() { /*...*/ }();
> 
> Even the void operator can be used:
> void function () { /*...*/ }();

Even nothing can be used,
the final parenteses with parameters work then too,
try:

alert( function(a){alert(a)} ) // function(a){alert(a)}
// [no execution of the function here]

alert( !function(a){alert(a)} ) // false
// [no execution of the function here]

alert( function(a){alert(a)}('executed') ) // executed // undefined

alert( !function(a){alert(a)}('executed') ) // executed // true

alert( void function(a){alert(a)}('executed') ) // executed // undefined





-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#27556

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-05-07 21:31 +0200
Message-ID<migej4$beq$1@solani.org>
In reply to#27555
Evertjan. wrote:

> Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
> comp.lang.javascript:
> 
>> An Immediately-Invoked Function Expression (IIFE) is usually written as:
>> (function() { /* etc. */ })();
>>
>> But we can use unary operators instead of the wrapping parentheses too,
>> if we don't care about the return value of the IIFE:
>>
>> Even the void operator can be used:
>> void function () { /*...*/ }();
> 
> Even nothing can be used,
> the final parenteses with parameters work then too,
> try:
> 
> alert( function(a){alert(a)} ) // function(a){alert(a)}
> // [no execution of the function here]

That works, because the IIFE is parsed in an expression context.  If the
IIFE is placed where a statement is expected, that would be a syntax
error. The whole point of using parens or an operator is to enforce an
expression context.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#27557

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-07 22:20 +0200
Message-ID<XnsA493E3574B657eejj99@194.109.133.246>
In reply to#27556
"Christoph M. Becker" <cmbecker69@arcor.de> wrote on 07 mei 2015 in 
comp.lang.javascript:

> Evertjan. wrote:
> 
>> Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
>> comp.lang.javascript:
>> 
[..]
>>> Even the void operator can be used:
>>> void function () { /*...*/ }();
>> 
>> Even nothing can be used,
>> the final parenteses with parameters work then too,
>> try:
>> 
>> alert( function(a){alert(a)} ) // function(a){alert(a)}
>> // [no execution of the function here]
> 
> That works, because the IIFE is parsed in an expression context.  If the
> IIFE is placed where a statement is expected, that would be a syntax
> error.

Indeed, so you can use this [the first is sort of standard]:

var r = function(a){alert(a)} // no execution yet!
alert(r) // function(a){alert(a)}

var r = function(a){alert(a)}('execution') // execution
alert(r) // undefined

> The whole point of using parens or an operator is

Not true.

While that could be your point, 
it was not the point of the OP, who was just Qing.

Methinks understanding how it works 
is an important prerequisite for why it is used.  

>  to enforce an expression context.

No "expression context" [I hope you mean 'scope'] is forced,
the return value is just accepted as required.

(function(a){alert(a)}('hi')) // hi

This works like void.

>> An Immediately-Invoked Function Expression (IIFE) is usually written as:
>> (function() { /* etc. */ })();

THIS DOES NOT WORK!

============================================

But why does this work:

-function(a){alert(a);return 2}('hi')

and this does not:

function(a){alert(a);return -2}('hi')

??

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#27560

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-05-07 23:27 +0200
Message-ID<miglc1$4s6$1@solani.org>
In reply to#27557
Evertjan. wrote:

> "Christoph M. Becker" <cmbecker69@arcor.de> wrote on 07 mei 2015 in 
> comp.lang.javascript:
> 
>>  to enforce an expression context.
> 
> No "expression context" [I hope you mean 'scope'] is forced,
> the return value is just accepted as required.

No, I don't mean "scope".  I was referring to *parsing*; however, the
term "expression context" might be misleading.

> But why does this work:
> 
> -function(a){alert(a);return 2}('hi')
>
> and this does not:
> 
> function(a){alert(a);return -2}('hi')
> 
> ??

This is a syntax issue.  See annex A of ECMA-262 5.1 Edition[1].  The
first line is parsed as (simplified)

  SourceElement -> Statement -> Expression -> UnaryExpression -> -
UnaryExpression -> - FunctionExpression Arguments -> ...

while the second line is parsed as (again simplified)

  SourceElement -> FunctionDeclaration -> ...

and the remaining ('hi') is a syntax error, as no ASI applies here.

[1] <http://www.ecma-international.org/ecma-262/5.1/#sec-A>

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#27562

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-05-08 00:26 +0200
Message-ID<migoq0$gvm$1@solani.org>
In reply to#27560
I wrote:

> Evertjan. wrote:
> 
> 
>> But why does this work:
>>
>> -function(a){alert(a);return 2}('hi')
>>
>> and this does not:
>>
>> function(a){alert(a);return -2}('hi')
>>
>> ??
> 
> while the second line is parsed as (again simplified)
> 
>   SourceElement -> FunctionDeclaration -> ...
> 
> and the remaining ('hi') is a syntax error, as no ASI applies here.

That's wrong.  According to ES 5.1 the line can't be parsed as
FunctionDeclaration, because the Identifier is missing.  Actually, the
code doesn't match any production, and as such is syntactically invalid.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#27563

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-08 11:00 +0200
Message-ID<XnsA4946FEC2688Ceejj99@194.109.133.246>
In reply to#27562
"Christoph M. Becker" <cmbecker69@arcor.de> wrote on 08 mei 2015 in 
comp.lang.javascript:

>>> -function(a){alert(a);return 2}('hi')
>>>
>>> and this does not:
>>>
>>> function(a){alert(a);return -2}('hi')
>>>
>>> ??
>> 
>> while the second line is parsed as (again simplified)
>> 
>>   SourceElement -> FunctionDeclaration -> ...
>> 
>> and the remaining ('hi') is a syntax error, as no ASI applies here.
> 
> That's wrong.  According to ES 5.1 the line can't be parsed as
> FunctionDeclaration, because the Identifier is missing.  Actually, the
> code doesn't match any production, and as such is syntactically invalid.

Quite, but that doesn't explain why

!function(a){alert(a)}('ho');
+function(a){alert(a)}('ho');
-function(a){alert(a)}('ho');

... do not throw an error.

"syntactically invalid" is just "according to the rules",
"throwing an error" is what should concern us in practice.

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#27992

FromJames Lewis <lewisje@gmail.com>
Date2015-06-05 09:10 -0700
Message-ID<dfa507f9-7e3f-46d3-97d3-965ab124b114@googlegroups.com>
In reply to#27563
On Friday, May 8, 2015 at 5:00:19 AM UTC-4, Evertjan. wrote:
> "Christoph M. Becker" <cmbecker69@arcor.de> wrote on 08 mei 2015 in 
> comp.lang.javascript:
> 
> >>> -function(a){alert(a);return 2}('hi')
> >>>
> >>> and this does not:
> >>>
> >>> function(a){alert(a);return -2}('hi')
> >>>
> >>> ??
> >> 
> >> while the second line is parsed as (again simplified)
> >> 
> >>   SourceElement -> FunctionDeclaration -> ...
> >> 
> >> and the remaining ('hi') is a syntax error, as no ASI applies here.
> > 
> > That's wrong.  According to ES 5.1 the line can't be parsed as
> > FunctionDeclaration, because the Identifier is missing.  Actually, the
> > code doesn't match any production, and as such is syntactically invalid.
> 
> Quite, but that doesn't explain why
> 
> !function(a){alert(a)}('ho');
> +function(a){alert(a)}('ho');
> -function(a){alert(a)}('ho');
> 
> ... do not throw an error.
> 
> "syntactically invalid" is just "according to the rules",
> "throwing an error" is what should concern us in practice.
> 
> -- 
> Evertjan.
> The Netherlands.
> (Please change the x'es to dots in my emailaddress)

On Friday, May 8, 2015 at 5:00:19 AM UTC-4, Evertjan. wrote:
> "Christoph M. Becker" <cmbecker69@arcor.de> wrote on 08 mei 2015 in 
> comp.lang.javascript:
> 
> >>> -function(a){alert(a);return 2}('hi')
> >>>
> >>> and this does not:
> >>>
> >>> function(a){alert(a);return -2}('hi')
> >>>
> >>> ??
> >> 
> >> while the second line is parsed as (again simplified)
> >> 
> >>   SourceElement -> FunctionDeclaration -> ...
> >> 
> >> and the remaining ('hi') is a syntax error, as no ASI applies here.
> > 
> > That's wrong.  According to ES 5.1 the line can't be parsed as
> > FunctionDeclaration, because the Identifier is missing.  Actually, the
> > code doesn't match any production, and as such is syntactically invalid.
> 
> Quite, but that doesn't explain why
> 
> !function(a){alert(a)}('ho');
> +function(a){alert(a)}('ho');
> -function(a){alert(a)}('ho');
> 
> ... do not throw an error.
> 
> "syntactically invalid" is just "according to the rules",
> "throwing an error" is what should concern us in practice.
> 
> -- 
> Evertjan.
> The Netherlands.
> (Please change the x'es to dots in my emailaddress)

First of all, Javascript that turns out to be syntactically invalid following Automatic Semicolon Insertion *will* throw an error (known as a "SyntaxError"); if it's in the main program code, the error will be thrown at compile-time and keep the script from running, while if it's in a string passed to eval or its relatives, the error will be thrown at runtime (this, in a try-catch block, is a good way to test for the support of new syntax).

Meanwhile, an example of "according to the rules" vs. "breaking the rules, but not throwing an error" would be anything that is changed by ASI and still runs, like
(function(){return this;}());
vs.
(function(){return this}());

Second, the way I understand function declarations vs. expressions is that if the keyword "function" appears at what could be the start of a statement, an ECMAScript implementation will try to parse the definition (from that keyword to the last matched right-brace) as a FunctionDeclaration, but if the keyword couldn't start a statement (for example, appearing right after a unary operator or an open left-parenthesis), it will be parsed as a FunctionExpression; it is an error to have a FunctionDeclaration without a name, or to have a call operator at the end of a FunctionDeclaration (it is also an error in most implementations, including the ECMAScript standards, to have a FunctionDeclaration inside a block that is not the top level of a function body, but others instead refer to that a FunctionStatement, a non-standard extension of JS), and once the parser decides to try to parse a FunctionDeclaration, it doesn't go back to try to parse it as a FunctionExpression just because it found a syntax error.
(I realize that a FunctionDeclaration is not a Statement, and in particular it doesn't end with a semicolon like a Statement does, but I also know that if you can't start a Statement in a particular place, you can't start a FunctionDeclaration there either.)

In short, if the beginning of a function expression *looks* like the start of a declaration, the parser will just try parsing it as a declaration and your program will break if it can't.

(This is similar to why you can't start a statement with an object initializer: It's interpreted instead as the start of a block, because they both start with the left-brace token.)

-James Edward Lewis II

[toc] | [prev] | [next] | [standalone]


#27739

FromScott Sauyet <scott.sauyet@gmail.com>
Date2015-05-18 13:31 -0700
Message-ID<f2a00d8a-1045-45f5-b5cb-95aeaca3b984@googlegroups.com>
In reply to#27557
Evertjan. wrote:
> Christoph M. Becker wrote 
>> Evertjan. wrote:

>>> But why does this work:
>>>|
>>>| -function(a){alert(a);return 2}('hi')
>>>|
>>>> and this does not:
>>>|
>>>| function(a){alert(a);return -2}('hi')
>>>| 
>>> while the second line is parsed as (again simplified)
>>> 
>>>   SourceElement -> FunctionDeclaration -> ...
>>> 
>>> and the remaining ('hi') is a syntax error, as no ASI applies here.
>> 
>> That's wrong.  According to ES 5.1 the line can't be parsed as
>> FunctionDeclaration, because the Identifier is missing.  Actually, the
>> code doesn't match any production, and as such is syntactically invalid.
> 
> Quite, but that doesn't explain why
> 
> !function(a){alert(a)}('ho');
> +function(a){alert(a)}('ho');
> -function(a){alert(a)}('ho');
> 
> ... do not throw an error.
> 
> "syntactically invalid" is just "according to the rules",
> "throwing an error" is what should concern us in practice.


Ok, so we'll try to simplify a bit:

-----

Parry Parser is very excited. He has not one, but two brand new programs 
to evaluate. He hasn't had this much fun since the last page was loaded! 

Linda Lexer is out sick, and so he'll be working today with Tommy 
Tokenizer. He's never really figured out why they have different titles, 
or understood what they claim to do differently. Come to think of it, no 
one has ever seen Tommy and Linda together... But, never mind that; he 
doesn't mind much. Tommy is almost as much fun as Linda. 

Parry prepares himself for his adventure, clearing off all the stacks he 
uses to hold things. He takes a deep breath, grins widely, and says, 
"Tommy, are you ready?" 

Tommy Tokenizer likes his job very much. There are those who think of 
him as a lowly character-fondler, but he knows that without him, the 
whole enterprise would crash to a halt. He's very content in his life. 
However, Parry can be pretty demanding, so Tommy also takes a very deep 
breath, looks around to make sure he hasn't left any spare punctuation 
lying around, and responds, "All set, Parry. Let's do this." 

Parry gets himself into program mode and passes Tommy the pointer to a 
stream of text. 

Tommy grabs the first character. It's an "f". No introductory white 
space on this job. "No rest for the weary," grumbles Tommy, reaching for 
another character. A "u", and then an "n". "Hey, this starts with 
'fun'," Tommy notices. But he doesn't tell Parry. Parry never wants to 
hear Tommy's little observations; Rhonda Regex is so much more pleasant. 

Tommy gets all the way to another "n" and then hits a "(". "Aha." Tommy 
is ready to give Parry something useful: "Okay, Parry, we have your 
first token, it's 'function', " and according to Kelly Keyword over in 
accounting, this is one of theirs." 

This is the moment Parry's been waiting for. He has a token. He grabs 
the rule-books and looks up the rules for the keyword "function", 
determines exactly what state he can enter next, and pushes "function" 
on top of one of the many empty stacks he has laying around his desk. He 
pushes the button on his desk that lights up a bulb in Tommy's room. 
Parry is ready for his next token! 

Tommy mutters something about how long that took Parry, but grabs the 
next character, an "a". Well that was quick. It means that the "(" 
stands all by itself. Poor things. Well, maybe Tommy can grab a cat-nap 
while Parry tries to figure out what to do with this one. "Here you go, 
Parry," he says, "It's a bouncing, baby '('." 

Parry checks the rule-books. Then he double-checks them. By the third 
time he's pretty sure. He's in the production 

    Program > SourceElements > SourceElement > FunctionDeclaration
    
And that is defined as 

    function Identifier ( FormalParameterListopt ) { FunctionBody }

He already has "function". He needs an Identifier. He quadruple-checks 
the rule-books, just to make sure. But no, an Identifier consists of an 
IdentifierName that is not a ReservedWord. And and IdentifierName has to 
start with a UnicodeLetter, a "$", a "_" or a UnicodeEscapeSequence. 
Someone has fed him a bad program! 

Now, gentle reader, you might think that this will dishearten our hero. 
After all, his job is to parse programs, and he is barely into this one. 
Well, nothing could be further from the truth. In fact, Parry is in 
heaven. He gets to sound the alarm! Most of the parsers in the office 
have a button on their desk for this, but Parry really enjoys this part 
of the job, and a few years before, he had a church-bell installed 
outside his office window rigged with pulleys. Parry walks... well he 
jogs... in all honesty, he runs to the corner of his room and begins 
vigorously tugging on the rope, announcing a syntax error to everyone. 

Tommy hears the signal, sighs, shakes his head at Parry's ridiculous 
exuberance, and cleans up his desk, tossing the remaining "a" into the 
vowel recycling bin, hoping that the cleaning crew wouldn't mix this bin 
with the trash. The ongoing vowel shortage in Bosnia has been keeping 
Tommy up nights. 

Holga Host-Environment pushes her head through Tommy's door for a little 
heart-felt one-on-one chat with her staff member. It's always good to 
give them encouragement. "Hey, I heard you caught that syntax error in 
just two tokens. Great job! It's folks like you that keep this place 
running!" And she pops back out. 

Parry heads back to clear off his desk. Bell-ringing is fun, but nothing 
will stop the flow of progress. There is another program to parse. 

Holga Host-Environment pushes her head through Parry's door for a little 
heart-felt one-on-one chat with her staff member. It's always good to 
give them encouragement. "Hey, I heard you caught that last syntax error 
in just two tokens. Great job! It's folks like you that keep this place 
running!" And she pops back out. 

Parry has come down a little from the highs of working through his first 
program so quickly. His desk is once again immaculate. He's ready for 
the next challenge. He double-checks with Tommy Tokenizer. It really is 
too bad that Linda Lexer couldn't be there today. Tommy just doesn't 
show the proper enthusiasm for the job. Well that's all right. Tommy's 
fast and accurate. Tommy tells him that he's ready, and Parry starts him 
off with a shiny new character stream. 

Again Tommy has no time to pause. This stream also starts with no white 
space. What are these people, workaholics? The first one is a "-". "I 
guess we don't start with 'fun' this time, he grumbles. But he's almost 
wrong. The next character is an "f", so he gets to pass the "-" 
immediately to Parry as the first token, and then it's deja vu all over 
again, as the "f" is followed by "u", and "n", and everything else 
necessary to make "function". Tommy is getting a bad feeling about this. 
It's looking awful familiar. 

But to Parry, things are entirely different. That initial "-" opens a 
world of possibilities... 

[... twenty tokens later ...] 

"That's it," Tommy tells Parry, "That ')' was the very last token." 

"Thanks, Tommy," says Parry, "a very good job, as always. Such a 
pleasure to work with a dedicated professional." Holga, it seems, has 
been rubbing off on him. 

Tommy cleans up his desk again and saunters over to his couch for a 
well-earned nap. 

Now is the critical moment. This is why they pay Parry the big bucks. He 
looks at what he has on the tops of his stacks. Is it legitimate? Is it 
unambiguous? Surely they wouldn't have fed him two bad programs in a 
row. The gods wouldn't be so cruel! An true enough, he has a 
well-constructed abstract syntax tree consisting of a `Program` 
containing an `ExpressionStatement` that starts with a "-" and is 
followed by a `CallExpression` containing a function and a one-argument 
list. He calls Holga to tell her the good news, and is somewhat put out 
that by the time he gets to "a `BlockStatement` consisting of an 
`ExpressionStatement` and a `ReturnStatement`", she cuts him off rather 
brusquely with her signature hurried tone, "Yes, yes, put it in the 
report". 

Well, Parry prides himself in his AST reports, and Gentle Reader, we'll 
leave him here polishing that report, quietly whistling to himself. 


-----

Is that simple enough?

-----
All software systems appearing in this work are fictitious. Any 
resemblance to real algorithms, loaded or on disk, is purely 
coincidental. 



  -- Scott

[toc] | [prev] | [next] | [standalone]


#27748

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-05-19 01:39 +0200
Message-ID<555A784D.5050700@arcor.de>
In reply to#27739
Scott Sauyet wrote:

> Evertjan. wrote:
>
>> Christoph M. Becker wrote 
>>
>>> That's wrong.  According to ES 5.1 the line can't be parsed as
>>> FunctionDeclaration, because the Identifier is missing.  Actually, the
>>> code doesn't match any production, and as such is syntactically invalid.
>>
>> Quite, but that doesn't explain why
>>
>> !function(a){alert(a)}('ho');
>> +function(a){alert(a)}('ho');
>> -function(a){alert(a)}('ho');
>>
>> ... do not throw an error.
>>
>> "syntactically invalid" is just "according to the rules",
>> "throwing an error" is what should concern us in practice.
> 
> Ok, so we'll try to simplify a bit:

<snipped the story of Parry Parser and his colleagues>

A wonderful story – thanks for telling, Scott.  And a really fine
explanation of the interaction of parsers and scanners (aka
lexers/tokenizers).

Actually, I would like to see the story in a FAQ note.  Maybe chapter 4,
Function, should be augmented by a section about "Why is there an
operator before `function`?" (or similar), which explains the issue
shortly, and links to the full story.

Thoughts?

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#27756

FromScott Sauyet <scott.sauyet@gmail.com>
Date2015-05-19 05:48 -0700
Message-ID<47713633-bc93-4169-8306-c5768c2f1827@googlegroups.com>
In reply to#27748
Christoph M. Becker wrote:
> Scott Sauyet wrote:
>> Evertjan. wrote:
>>> Christoph M. Becker wrote 
>>>
>>>> That's wrong.  According to ES 5.1 the line can't be parsed as
>>>> FunctionDeclaration, because the Identifier is missing.  Actually, the
>>>> code doesn't match any production, and as such is syntactically invalid.
>>>
>>> Quite, but that doesn't explain why
>>>
>>> !function(a){alert(a)}('ho');
>>> +function(a){alert(a)}('ho');
>>> -function(a){alert(a)}('ho');
>>>
>>> ... do not throw an error.
>>>
>>> "syntactically invalid" is just "according to the rules",
>>> "throwing an error" is what should concern us in practice.
>> 
>> Ok, so we'll try to simplify a bit:
>
> <snipped the story of Parry Parser and his colleagues>
> 
> A wonderful story - thanks for telling, Scott.  And a really fine
> explanation of the interaction of parsers and scanners (aka
> lexers/tokenizers).

Thanks.  Originally, I was planning on being much more detailed about
the various productions involved in these two snippets.  But I realized
that even as short as they were, this would quickly become too tedious.


> Actually, I would like to see the story in a FAQ note.  Maybe chapter 4,
> Function, should be augmented by a section about "Why is there an
> operator before `function`?" (or similar), which explains the issue
> shortly, and links to the full story.
> 
> Thoughts?

While I don't object, obviously this was meant as a lark, and certain
liberties have been taken that might not meet the more scholarly 
expectations involved in the FAQ, even for its notes.

Someone who wants to put it in there is welcome to do so.  


  -- Scott

[toc] | [prev] | [next] | [standalone]


#27558

FromJoao Rodrigues <groups_jr-1@yahoo.com.br>
Date2015-05-07 17:47 -0300
Message-ID<migj0l$b6e$1@speranza.aioe.org>
In reply to#27556
On 07/05/2015 16:31, Christoph M. Becker wrote:

> The whole point of using parens or an operator is to enforce an
> expression context.
> 

Brilliant! That sums it up.

-- 
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#27559

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-07 23:22 +0200
Message-ID<XnsA493EDC10C34Ceejj99@194.109.133.246>
In reply to#27558
Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
comp.lang.javascript:

> On 07/05/2015 16:31, Christoph M. Becker wrote:
> 
>> The whole point of using parens or an operator is to enforce an
>> expression context.
>> 
> 
> Brilliant! That sums it up.

Well no, it does not.

It does not cover the "how".

And it does not force a "scope", if that was ment 
by the stange wording "expression context".

If there is a point, 
it must be just to suppress the error of not allowing
a anonymous function to have a return value go into limbo.

The "how" is not even clear, 
as the ! just changes the value to boolean, 
and the + an - just make it numeric.

It seems orphan return values are allowed,
as long as they don't originate from a anonymous function:

'hi'; alert('x');
2+7; alert('y');

Anyone?

- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [next] | [standalone]


#27561

FromJoao Rodrigues <groups_jr-1@yahoo.com.br>
Date2015-05-07 19:08 -0300
Message-ID<mignok$n1n$1@speranza.aioe.org>
In reply to#27559
On 07/05/2015 18:22, Evertjan. wrote:
> Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
> comp.lang.javascript:
> 
>> On 07/05/2015 16:31, Christoph M. Becker wrote:
>>
>>> The whole point of using parens or an operator is to enforce an
>>> expression context.
>>>
>>
>> Brilliant! That sums it up.
> 
> Well no, it does not.
> 
> It does not cover the "how".
> 

This blog post explains the whys and the hows:
<http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife>


-- 
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#27564

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2015-05-08 12:08 +0200
Message-ID<XnsA4947B9177DAEeejj99@194.109.133.246>
In reply to#27561
Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 08 mei 2015 in
comp.lang.javascript: 

> On 07/05/2015 18:22, Evertjan. wrote:
>> Joao Rodrigues <groups_jr-1@yahoo.com.br> wrote on 07 mei 2015 in 
>> comp.lang.javascript:
>> 
>>> On 07/05/2015 16:31, Christoph M. Becker wrote:
>>>
>>>> The whole point of using parens or an operator is to enforce an
>>>> expression context.
>>>
>>> Brilliant! That sums it up.
>> 
>> Well no, it does not.
>> 
>> It does not cover the "how".
> 
> This blog post explains the whys and the hows:
> <http://benalman.com/news/2010/11/immediately-invoked-function-expression
> /#iife> 

It explains the "why", and shows the "how".

It does not **explain** the "how",
meaning "why" the "how" works.

-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web