Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #27546 > unrolled thread
| Started by | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| First post | 2015-05-07 20:15 +1000 |
| Last post | 2015-05-08 12:08 +0200 |
| Articles | 19 — 8 participants |
Back to article view | Back to comp.lang.javascript
! 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
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2015-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]
| From | Joao Rodrigues <groups_jr-1@yahoo.com.br> |
|---|---|
| Date | 2015-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]
| From | JJ <jj4public@vfemail.net> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2015-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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]
| From | James Lewis <lewisje@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2015-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2015-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]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Joao Rodrigues <groups_jr-1@yahoo.com.br> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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]
| From | Joao Rodrigues <groups_jr-1@yahoo.com.br> |
|---|---|
| Date | 2015-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]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2015-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