Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Guidlines for Avoiding ASI-related errors

Reply
Thread Tools

Guidlines for Avoiding ASI-related errors

 
 
Garrett Smith
Guest
Posts: n/a
 
      05-16-2010
ASI - Automatic Semicolon Insertions

Semicolon is inserted in various places where a statement could be
terminated, but is not. General advice, taken from the specification,
with my own addition.

Semicolons
* A postfix ++ or -- operator should appear on the same line as its
operand.
* An Expression in a return or throw statement should start on the
same line as the return or throw token.
* An Identifier in a break or continue statement should be on the same
line as the break or continue token.
* Semicolons should appear explicitly where they are required.

The last one is my addition. It is debatable but generally true. What
follows a newline-ending expression determines whether the semicolon is
inserted or not.

The advice semicolons should appear explicitly where they are required
provides a general guideline that makes a program more resilient to
errors that could be introduced by minification or inadvertent changes
in source code whitespace, including whitespace in comments, and order
of expressions.

A FunctionExpression that is followed by a newline, then followed by
grouping operator, will be interpreted as a CallExpression, implicating
the FunctionExpression in the call. For example, if the developer wanted
to declare a MyWidget constructor, and then do some initializations in a
closure following it, he might use:

var MyWidget = function a(){
this.name = "mike";
}
/**
* Initialize Widget
*/
(function() {
/*...*/
});

- but the problem with that is that the FunctionExpression would be
called because the parentheses, which were intended to be a grouping
operator, were interpreted as a part of CallExpression, resulting in
MyWidget having the value undefined window.name getting the value
"mike", just as:

var MyWidget = function(){
this.name = "mike";
}(function(){});

- would have the same effect, more obviously.

Line terminators in comments may also affect ASI. If comment begins at
the end of an expression and it contains a line terminator, a semicolon
should be automatically inserted. Not all implementations will do that,
however.

For example:

var MyWidget = function a(){
return {toString: function(){return"widget"}};
}/*
*/g = 2;

Conforming implementations consider whitespace in comments and so the
program can run. JScript, however, does not run the program.

Consistent failure can be expected from:

var MyWidget = function(){
this.name = "mike";
}/** Initialize Widget */g = 2;

- because the comment following the FunctionExpression does not contain
a line terminator. If a line terminator is added, then the program
should be interpreted with a semicolon being automatically inserted
immediately following the FunctionExpression. As stated, not all
implementations do that.

From ES5, 5.1.2:
| A MultiLineComment (that is, a comment of the form /*...*/
| regardless of whether it spans more than one line) is likewise simply
| discarded if it contains no line terminator; but if a MultiLineComment
| contains one or more line terminators, then it is replaced by a single
| line terminator, which becomes part of the stream of input elements
| for the syntactic grammar.

Question: How does a MultiLineComment can span more than one line and
not contain a line terminator?

Regardless, the complexities of automatic semicolon insertion are
undesirable and should be avoided. The advice provided aims to help
avoid those problems.

Comments or suggestions?
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
 
Reply With Quote
 
 
 
 
John G Harris
Guest
Posts: n/a
 
      05-17-2010
On Sun, 16 May 2010 at 16:01:06, in comp.lang.javascript, Garrett Smith
wrote:
>ASI - Automatic Semicolon Insertions


'Insertion', singular, would read better.

>Semicolon


'A semicolon' would make it easier to read.

> is inserted in various places where a statement could be
>terminated, but is not. General advice, taken from the specification,
>with my own addition.
>
>Semicolons
> * A postfix ++ or -- operator should appear on the same line as its
>operand.
> * An Expression in a return or throw statement should start on the
>same line as the return or throw token.
> * An Identifier in a break or continue statement should be on the same
>line as the break or continue token.


'should' ought to be 'must' as it's not optional, not even slightly.
(Never mind what the standard says).

> * Semicolons should appear explicitly where they are required.
>
>The last one is my addition. It is debatable but generally true.


Maybe 'should' is a little too strong. Remember that some people are
violently opposed to using semicolons in a 'scripting' language. They
might be less annoyed if you said 'It is recommended, for the following
reasons, that' ...

>What follows a newline-ending expression determines whether the
>semicolon is inserted or not.
>
>The advice semicolons


'The advice that semicolons'

> should appear explicitly where they are required provides a general
>guideline that makes a program more resilient to errors that could be
>introduced by minification or inadvertent changes in source code
>whitespace, including whitespace in comments, and order of expressions.
>
>A FunctionExpression that is followed by a newline, then followed by
>grouping operator, will be interpreted as a CallExpression, implicating
>the FunctionExpression in the call. For example, if the developer
>wanted to declare a MyWidget constructor, and then do some
>initializations in a closure following it, he might use:
>
>var MyWidget = function a(){
> this.name = "mike";
>}
>/**
> * Initialize Widget
> */
>(function() {
> /*...*/
>});
>
>- but the problem with that is that the FunctionExpression would be
>called because the parentheses, which were intended to be a grouping
>operator, were interpreted as a part of CallExpression, resulting in
>MyWidget having the value undefined window.name getting the value
>"mike", just as:
>
>var MyWidget = function(){
> this.name = "mike";
>}(function(){});
>
>- would have the same effect, more obviously.
>
>Line terminators in comments may also affect ASI. If comment begins at


'If a comment'

>the end of an expression and it contains a line terminator, a semicolon
>should


'ought to'

>be automatically inserted. Not all implementations will do that,
>however.
>
>For example:
>
>var MyWidget = function a(){
> return {toString: function(){return"widget"}};
>}/*
>*/g = 2;
>
>Conforming implementations consider whitespace in comments and so the
>program can run.


Not really whitespace; they need only test for line terminators.

>JScript, however, does not run the program.


Shame!

>Consistent failure can be expected from:
>
>var MyWidget = function(){
> this.name = "mike";
>}/** Initialize Widget */g = 2;
>
>- because the comment following the FunctionExpression does not contain
>a line terminator. If a line terminator is added, then the program
>should be interpreted with a semicolon being automatically inserted
>immediately following the FunctionExpression. As stated, not all
>implementations do that.
>
>From ES5, 5.1.2:
>| A MultiLineComment (that is, a comment of the form /*...*/
>| regardless of whether it spans more than one line) is likewise simply
>| discarded if it contains no line terminator; but if a MultiLineComment
>| contains one or more line terminators, then it is replaced by a single
>| line terminator, which becomes part of the stream of input elements
>| for the syntactic grammar.
>
>Question: How does a MultiLineComment can span more than one line and
>not contain a line terminator?


Vertical tab and form feed can, on a glass teletype, make the text
multiline without there being a LineTerminator character.

>Regardless, the complexities of automatic semicolon insertion are
>undesirable and should be avoided. The advice provided aims to help
>avoid those problems.
>
>Comments or suggestions?


John
--
John Harris
 
Reply With Quote
 
 
 
 
Garrett Smith
Guest
Posts: n/a
 
      05-18-2010
John G Harris wrote:
> On Sun, 16 May 2010 at 16:01:06, in comp.lang.javascript, Garrett Smith
> wrote:
>> ASI - Automatic Semicolon Insertions

>
> 'Insertion', singular, would read better.
>
>> Semicolon

>
> 'A semicolon' would make it easier to read.
>


Yes it would.

>> is inserted in various places where a statement could be
>> terminated, but is not. General advice, taken from the specification,
>> with my own addition.
>>
>> Semicolons
>> * A postfix ++ or -- operator should appear on the same line as its
>> operand.
>> * An Expression in a return or throw statement should start on the
>> same line as the return or throw token.
>> * An Identifier in a break or continue statement should be on the same
>> line as the break or continue token.

>
> 'should' ought to be 'must' as it's not optional, not even slightly.
> (Never mind what the standard says).
>


You're right.

>> * Semicolons should appear explicitly where they are required.
>>
>> The last one is my addition. It is debatable but generally true.

>
> Maybe 'should' is a little too strong. Remember that some people are
> violently opposed to using semicolons in a 'scripting' language. They
> might be less annoyed if you said 'It is recommended, for the following
> reasons, that' ...
>
>> What follows a newline-ending expression determines whether the
>> semicolon is inserted or not.
>>
>> The advice semicolons

>
> 'The advice that semicolons'
>


Right. (I actually meant that as a quote; The advice "semicolons should
appear explicitly where they are required").

>> should appear explicitly where they are required provides a general
>> guideline that makes a program more resilient to errors that could be
>> introduced by minification or inadvertent changes in source code
>> whitespace, including whitespace in comments, and order of expressions.
>>


> 'If a comment'
>
>> the end of an expression and it contains a line terminator, a semicolon
>> should

>
> 'ought to'
>


'is'.

If a comment begins at the end of an expression and it contains a line
terminator, a semicolon is automatically inserted after the expression.

>> be automatically inserted. Not all implementations will do that,
>> however.
>>
>> For example:
>>
>> var MyWidget = function a(){
>> return {toString: function(){return"widget"}};
>> }/*
>> */g = 2;
>>
>> Conforming implementations consider whitespace in comments and so the
>> program can run.

>
> Not really whitespace; they need only test for line terminators.
>


Right.

>> JScript, however, does not run the program.

>
> Shame!
>


If ASI is avoided, it doesn't matter. The lineTerminator in comment is a
complicated aspect of ASI. ASI seems best avoided. The code using a
semicolon explicitly, where that is needed, costs only one character.

The specification does not mention non-restricted productions, such as
Grouping Operator, which can match Arguments, if preceded by a Token.

For example, in the first line, we have a CallExpression, and then
following that, an ArrayLiteral.

Here, we can see an example that "works":

var a = 0
var x = [].slice(document.childNodes)
var y = a--
[].splice.call(x);

- and when y is changed to pre-increment, the character '[' looks like
property Accessor, and so it is interpreted as that, and when ']' is
reached instead of an expression, a SyntaxError results.

var a = 0
var x = [].slice(document.childNodes)
var y = --a
[].splice.call(x);


And grouping operator accidentally becoming Arguments in CallExpression,
as shown earlier. Another example of that:

a.
var c = 19, b = 10;
var a = b + c
(a + b).toString()

b.
var c = 19, b = 10;
var a = b + c
(a + b).toString()


A program that uses semicolons explicitly is more resilient to changes
that could be introduced by minification, inadvertent changes in line
terminators, changes in order of expressions, and changes in comments.

I've included some of this in the Code Guidelines doc:

http://jibbering.com/faq/notes/code-guidelines/#asi

I wanted to include some examples where relying on ASI causes problems
but it ended up getting a little longer than I wanted.

>> Question: How does a MultiLineComment can span more than one line and
>> not contain a line terminator?

>
> Vertical tab and form feed can, on a glass teletype, make the text
> multiline without there being a LineTerminator character.
>

OK.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
 
Reply With Quote
 
Garrett Smith
Guest
Posts: n/a
 
      05-18-2010
Garrett Smith wrote:
> John G Harris wrote:
>> On Sun, 16 May 2010 at 16:01:06, in comp.lang.javascript, Garrett Smith
>> wrote:


[...]

> If a comment begins at the end of an expression and it contains a line
> terminator, a semicolon is automatically inserted after the expression.
>


Reread: That explanation is wrong.

A a MultiLineComment that contains a LineTerminator is replaced by a
LineTerminator. If that LineTerminator would result in a place where a
semicolon could be inserted, then a semicolon is inserted.

Fixed.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
 
Reply With Quote
 
John G Harris
Guest
Posts: n/a
 
      05-18-2010
On Tue, 18 May 2010 at 00:06:24, in comp.lang.javascript, Garrett Smith
wrote:
>Garrett Smith wrote:
>> John G Harris wrote:
>>> On Sun, 16 May 2010 at 16:01:06, in comp.lang.javascript, Garrett Smith
>>> wrote:


<snip>
Here is an additional comment.

It would be useful to add a remark that some statements do *not* end
with a semicolon. If you add a semicolon after one of these you are
adding an Empty statement, which can cause trouble in some
circumstances.

The statements that don't end in semicolon all end in close curly
bracket instead. They are :

Block -
{ ... }

Switch Statement -
switch ( ... ) { ... }

Try Statement -
try ... catch ( ... ) { ... }
try ... finally { ... }

And also there is something that isn't a statement but resembles one :

Function Declaration -
function ... { ... }


John
--
John Harris
 
Reply With Quote
 
Dr J R Stockton
Guest
Posts: n/a
 
      05-18-2010
In comp.lang.javascript message <hsptfn$2iv$(E-Mail Removed)-
september.org>, Sun, 16 May 2010 16:01:06, Garrett Smith
<(E-Mail Removed)> posted:

>ASI - Automatic Semicolon Insertions
>
>Semicolon is inserted in various places where a statement could be
>terminated, but is not. General advice, taken from the specification,
>with my own addition.
>
>Semicolons
> * A postfix ++ or -- operator should appear on the same line as its
>operand.


Advising against something which browsers etc. do not accept is hardly
necessary; and, if done, then use 'must' rather than 'should'.

> * Semicolons should appear explicitly where they are required.


If they are required, clearly they must appear. You have a meaning, but
your words do not express it.


One should disregard those who write and deploy code without any
testing; therefore there need be no concern about what browsers detect
as errors, or what the simplest test must discover. and locate easily.

I suggest listing all of the cases where, in ordinary code, semicolon
insertion might be mis-predicted without necessarily causing an
immediately-located error. A prime case there seems to be insertion
between a return and its expression.

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
 
Reply With Quote
 
Garrett Smith
Guest
Posts: n/a
 
      05-18-2010
John G Harris wrote:
> On Tue, 18 May 2010 at 00:06:24, in comp.lang.javascript, Garrett Smith
> wrote:
>> Garrett Smith wrote:
>>> John G Harris wrote:
>>>> On Sun, 16 May 2010 at 16:01:06, in comp.lang.javascript, Garrett Smith
>>>> wrote:

>
> <snip>
> Here is an additional comment.
>
> It would be useful to add a remark that some statements do *not* end
> with a semicolon. If you add a semicolon after one of these you are
> adding an Empty statement, which can cause trouble in some
> circumstances.
>


I thought of that, but realized that the case was not about formatting,
but about statements. The Statements section states:

"Do not use useless statements"

Is that too terse? Where is the right place for advice on
EmptyStatement? Should it go in "Statements" or does it belong under
"Formatting > Semicolons"?

The section "Formatting > "Semicolons", as it is written now, is focused
on how ASI affects a program and how to avoid that. A useless
EmptyStatement won't trigger an ASI related problem so advice on
EmptyStatement doesn't quite seem to fit there.

Should the section "Formatting > "Semicolons" include advice about when
not to include semicolon following the section on ASI? Should the
section on Statements mention that blocks don't need Semicolons? Or is
the section on Statements enough?
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
 
Reply With Quote
 
John G Harris
Guest
Posts: n/a
 
      05-19-2010
On Tue, 18 May 2010 at 14:35:37, in comp.lang.javascript, Garrett Smith
wrote:

<snip>
>I thought of that, but realized that the case was not about formatting,
>but about statements. The Statements section states:
>
> "Do not use useless statements"
>
>Is that too terse? Where is the right place for advice on
>EmptyStatement? Should it go in "Statements" or does it belong under
>"Formatting > Semicolons"?
>
>The section "Formatting > "Semicolons", as it is written now, is
>focused on how ASI affects a program and how to avoid that. A useless
>EmptyStatement won't trigger an ASI related problem so advice on
>EmptyStatement doesn't quite seem to fit there.
>
>Should the section "Formatting > "Semicolons" include advice about when
>not to include semicolon following the section on ASI? Should the
>section on Statements mention that blocks don't need Semicolons? Or is
>the section on Statements enough?


The trouble is that many people, not just beginners, are hazy about
statements and more so about where the implied semicolons go. They are
likely to insert semicolons almost at random without really knowing why.

If an error message says that an else is a syntax error then experienced
programmers will know to track backwards to see where the parser got
confused. Beginners tend to think that it's the else that's wrong and
waste a lot of time messing about, especially if they don't realise that
a semicolon can be causing the trouble.

That's why I think something should be said in the ASI part, even if
it's only a short sentence.

John
--
John Harris
 
Reply With Quote
 
John G Harris
Guest
Posts: n/a
 
      05-19-2010
On Tue, 18 May 2010 at 17:19:31, in comp.lang.javascript, Dr J R
Stockton wrote:
>In comp.lang.javascript message <hsptfn$2iv$(E-Mail Removed)-
>september.org>, Sun, 16 May 2010 16:01:06, Garrett Smith
><(E-Mail Removed)> posted:
>
>>ASI - Automatic Semicolon Insertions
>>
>>Semicolon is inserted in various places where a statement could be
>>terminated, but is not. General advice, taken from the specification,
>>with my own addition.
>>
>>Semicolons
>> * A postfix ++ or -- operator should appear on the same line as its
>>operand.

>
>Advising against something which browsers etc. do not accept is hardly
>necessary; and, if done, then use 'must' rather than 'should'.


Which browsers don't accept this :
a
++
b
and how many beginners know for sure how it ought to be parsed ?


<snip>
>One should disregard those who write and deploy code without any
>testing; therefore there need be no concern about what browsers detect
>as errors, or what the simplest test must discover. and locate easily.

<snip>

Provided you remember to test with browsers that do detect it as an
error.

John
--
John Harris
 
Reply With Quote
 
Garrett Smith
Guest
Posts: n/a
 
      05-19-2010
Dr J R Stockton wrote:
> In comp.lang.javascript message <hsptfn$2iv$(E-Mail Removed)-
> september.org>, Sun, 16 May 2010 16:01:06, Garrett Smith
> <(E-Mail Removed)> posted:
>
>> ASI - Automatic Semicolon Insertions
>>


[...]

>> * Semicolons should appear explicitly where they are required.

>
> If they are required, clearly they must appear. You have a meaning, but
> your words do not express it.
>


Certain statements are required to be terminated by a semicolon.

When a required semicolon is not explicitly supplied, one is
automatically inserted in certain situations.

Explicit use of required semicolons can help to avoid some problems with
ASI. Those problems are explained.

The current wording in the code guidelines document, in context:

| ASI Guidelines for Semicolons in Source Code:
|
| * Don't rely on ASI. Use semicolons explicitly.
|
| Productions that are not restricted can be created accidentally where
| ASI has been used. This is often the result of where the developer
| forgot to use a semicolon. Regardless, the problems it creates can
| occur when the order of Statements changes or when line terminators
| are added or removed, including those that appear in comments. Where
| semicolons are needed, it is recommended that they appear explicitly.
|

That paragraph is followed by explanation and examples.

>
> One should disregard those who write and deploy code without any
> testing; therefore there need be no concern about what browsers detect
> as errors, or what the simplest test must discover. and locate easily.
>
> I suggest listing all of the cases where, in ordinary code, semicolon
> insertion might be mis-predicted without necessarily causing an
> immediately-located error. A prime case there seems to be insertion
> between a return and its expression.
>

That is only one of the three on the list.

ASI Guidelines for restricted productions:

| * A postfix ++ or -- operator must appear on the same line as its
| operand.
| * An Expression in a return or throw statement must start on the same
| line as the return or throw token.
| * An Identifier in a break or continue statement must be on the same
| line as the break or continue token.

John G Harris addressed postfix operators with an example. Are the cases
with `throw` and `break` confusing? If can provide an example if that is
necessary.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Avoiding errors due to bad email addresses Nathan Sokalski ASP .Net 1 11-16-2005 09:12 PM
mcsd exam guidlines john MCSD 0 11-22-2004 12:33 PM
Internet Explorer causing errors/ slow internet speed and Outlook express errors Jeanne Medley Computer Support 2 02-11-2004 11:44 PM
Errors, errors, errors Mark Goldin ASP .Net 2 01-17-2004 08:05 PM
preparing for 70-016 :Guidlines? Badri prasad MCSD 0 01-16-2004 06:14 PM



Advertisments