SlideShare a Scribd company logo
By Mike Wilcox
May 2012
The Great Semicolon
                 Debate
By Mike Wilcox
May 2012
or how the semicolon
     may bring down society
By Mike Wilcox
May 2012
By Mike Wilcox
May 2012
What does a semicolon
look like?
What does a semicolon
look like?
What does a semicolon
look like?
What does a semicolon
look like?
What does a semicolon
look like?




      ~
      ~   !
What does a semicolon
look like?




      ~
      ~   !
What does a semicolon
look like?




      ~
      ~   !
In Other Languages
In Other Languages
English:       ;
In Other Languages
English:       ;
French:        ;
In Other Languages
English:       ;
French:        ;
Spanish:       ;
In Other Languages
English:       ;
French:        ;
Spanish:       ;
Wingdings 1:   
In Other Languages
English:       ;
French:        ;
Spanish:       ;
Wingdings 1:   
Wingdings 2:   
In Code
In Code
In CSS:
 Semicolons are REQUIRED
In Code
In CSS:
 Semicolons are REQUIRED
background:#ff0000;
In Code
In CSS:
 Semicolons are REQUIRED
background:#ff0000;

In HTML:
 Semicolons are NOT USED
In Code
In CSS:
 Semicolons are REQUIRED
background:#ff0000;

In HTML:
 Semicolons are NOT USED

<div class=”awesomeness”>bob</div>
In Code
In CSS:
 Semicolons are REQUIRED
background:#ff0000;

In HTML:
 Semicolons are NOT USED

<div class=”awesomeness”>bob</div>

In JavaScript:
  Semicolons are... OPTIONAL
In Code
In CSS:
 Semicolons are REQUIRED
background:#ff0000;

In HTML:
 Semicolons are NOT USED

<div class=”awesomeness”>bob</div>

In JavaScript:
  Semicolons are... OPTIONAL


           Hence, the CONTROVERSY!
Example
Example
Is this correct?
var test = function(){
! console.log('Hello World')
}
Example
Is this correct?
var test = function(){
! console.log('Hello World')
}



Or this?
var test = function(){
! console.log('Hello World');
};
Example
Is this correct?
var test = function(){
! console.log('Hello World')
}



Or this?
var test = function(){
! console.log('Hello World');
};




Answer: both!
ASI
ASI
Automatic Semicolon Insertion
ASI
Automatic Semicolon Insertion
 Certain ECMAScript statements (empty statement,
 variable statement, expression statement, do-while
 statement, continue statement, break statement, return
 statement, and throw statement) must be terminated
 with semicolons.
ASI
Automatic Semicolon Insertion
 Certain ECMAScript statements (empty statement,
 variable statement, expression statement, do-while
 statement, continue statement, break statement, return
 statement, and throw statement) must be terminated
 with semicolons.

 For convenience, however, such semicolons may be
 omitted from the source text in certain situations.
ASI
Automatic Semicolon Insertion
 Certain ECMAScript statements (empty statement,
 variable statement, expression statement, do-while
 statement, continue statement, break statement, return
 statement, and throw statement) must be terminated
 with semicolons.

 For convenience, however, such semicolons may be
 omitted from the source text in certain situations.


 These situations are described by saying that
 semicolons are automatically inserted into the source
 code token stream in those situations.
Uh, no. I really
didn’t get that.
ASI   (simplified)
ASI  (simplified)
Automatic Semicolon Insertion
ASI  (simplified)
Automatic Semicolon Insertion
 Other than continue, break, return, and throw,
 JavaScript will consider a newline to be the end of
 your expression.
ASI Examples
ASI Examples
var foo = 3
var bar = “foo”
var myObject = {
  a:1,
  b:2
}
doSomething()
while(a < 1){
  b++
}
return buzz
ASI Examples
var foo = 3
var bar = “foo”
var myObject = {
  a:1,
  b:2
}
doSomething()
while(a < 1){
  b++
}
return buzz


No semicolons needed!
What’s the Point?
What’s the Point?
ASI Examples
ASI Examples
Does this work?
ASI Examples
Does this work?

var foo = 1+2
('bob' + 'guru').toUpperCase()
ASI Examples
Does this work?

var foo = 1+2
('bob' + 'guru').toUpperCase()


ERROR: number is not a function
ASI Examples
Does this work?

var foo = 1+2
('bob' + 'guru').toUpperCase()


ERROR: number is not a function

JavaScript sees that code like this:
ASI Examples
Does this work?

var foo = 1+2
('bob' + 'guru').toUpperCase()


ERROR: number is not a function

JavaScript sees that code like this:

var foo = 1+2('bob' + 'guru').toUpperCase();
Uhhh... I thought you
   said JavaScript will
consider a newline to be
     the end of your
       expression.
ASI
ASI
 A semicolon is not implied at the end of a line if the
 first token of the subsequent line can be parsed as part
 of the same statement.
ASI
 A semicolon is not implied at the end of a line if the
 first token of the subsequent line can be parsed as part
 of the same statement.

 There are five tokens that can appear both at the start
 of a statement, and as an extension of a complete
 statement. These tokens are the open parenthesis
 ( open square brace [ slash or solidus /, and + and -.
ASI
 A semicolon is not implied at the end of a line if the
 first token of the subsequent line can be parsed as part
 of the same statement.

 There are five tokens that can appear both at the start
 of a statement, and as an extension of a complete
 statement. These tokens are the open parenthesis
 ( open square brace [ slash or solidus /, and + and -.


 In particular, these will cause you problems:
 (
 [
ASI Examples
ASI Examples
Does this work?
ASI Examples
Does this work?
var foo = 'asdf'
[1,2,3].forEach(function(n){log(n)})
ASI Examples
Does this work?
var foo = 'asdf'
[1,2,3].forEach(function(n){log(n)})


"asdf"[1, 2, 3].forEach is not a function
ASI Examples
Does this work?
var foo = 'asdf'
[1,2,3].forEach(function(n){log(n)})


"asdf"[1, 2, 3].forEach is not a function


What’s wrong with this?
ASI Examples
Does this work?
var foo = 'asdf'
[1,2,3].forEach(function(n){log(n)})


"asdf"[1, 2, 3].forEach is not a function


What’s wrong with this?

i=0
/[a-z]/g.exec(s)
ASI Examples
Does this work?
var foo = 'asdf'
[1,2,3].forEach(function(n){log(n)})


"asdf"[1, 2, 3].forEach is not a function


What’s wrong with this?

i=0
/[a-z]/g.exec(s)


a is not defined
ASI Examples
ASI Examples
What does this return?
ASI Examples
What does this return?
return
1 + 2
ASI Examples
What does this return?
return
1 + 2


undefined
ASI Examples
What does this return?
return
1 + 2


undefined

Remember, continue, break, return, and throw are
exceptions and must end with a semicolon. ASI is not
used.
ASI Examples
What does this return?
return
1 + 2


undefined

Remember, continue, break, return, and throw are
exceptions and must end with a semicolon. ASI is not
used.


return(
  1 + 2
)
ASI Examples
What does this return?
return
1 + 2


undefined

Remember, continue, break, return, and throw are
exceptions and must end with a semicolon. ASI is not
used.


return(
  1 + 2
)

This works.
Newbie does what
Newbie does what
You might think the solution is to add a semicolon to
the end of every line...
Newbie does what
You might think the solution is to add a semicolon to
the end of every line...

if(true){
  doSomething();
};

function doBob(){
  return “do not”;
};
Newbie does what
You might think the solution is to add a semicolon to
the end of every line...

if(true){
  doSomething();
};

function doBob(){
  return “do not”;
};



Not an error! But... JSLint says:
“unexpected semicolon.”
Newbie does what
You might think the solution is to add a semicolon to
the end of every line...

if(true){
                                    If yo u put
  doSomething();                                 o ne
};                                 here... there
                                                ’s no
function doBob(){                    helping yo u
                                                   r
  return “do not”;
};                                      cause.


Not an error! But... JSLint says:
“unexpected semicolon.”
No ASI to see here
No ASI to see here
Semicolons should not be used for block statements.
No ASI to see here
Semicolons should not be used for block statements.

if(true){
  doSomething();
}

function doBob(){
  return “do not”;
}

while(true){
  doBob();
}

for(var ba=0; ba<beer.left; ba++){
  drink++;
}
This is News?
This is News?
The Trigger




      https://github.com/twitter/bootstrap/issues/3057
The Trigger




clearMenus()
!isActive && $parent.toggleClass(‘open’)




            https://github.com/twitter/bootstrap/issues/3057
The Response
The Response
The Response
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on Github
The Battle on LinkedIn
The Battle on LinkedIn
The Battle on LinkedIn
The Battle on LinkedIn
The Battle on LinkedIn
Library Solution
Library Solution
Library Solution
        Tho mas Fu
                   chs,
          author of
        Scriptaculo
                    us
Library Solution
        Tho mas Fu
                   chs,
          author of
        Scriptaculo
                    us
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
(fake) Fat Twitter Feed
Brendan Makes it Clear.
Brendan Makes it Clear.
  Most of the comments in
the semicolons exchange make
           me sad.
Brendan Makes it Clear.
  Most of the comments in
                                   In the proposed promises
the semicolons exchange make
                               grammar and you’ll see something
           me sad.
                                 surprising about ASI and infix
                                operators: we can add new infix
                                    operators in the future.
Brendan Makes it Clear.
  Most of the comments in
                                                In the proposed promises
the semicolons exchange make
                                            grammar and you’ll see something
           me sad.
                                              surprising about ASI and infix
                                             operators: we can add new infix
                                                 operators in the future.




  let flag = x is y;           // no n before 'is'!
  x ! p = v;                   // Q(x).put(’p’, v)
Brendan Makes it Clear.
  Most of the comments in
                                                 In the proposed promises
the semicolons exchange make
                                             grammar and you’ll see something
           me sad.
                                               surprising about ASI and infix
                                              operators: we can add new infix
                                                  operators in the future.



                                                      The moral of this
                                              story: ASI is (formally speaking)
                                                 a syntactic error correction
                                            procedure. If you start to code as if
                                               it were a universal significant-
                                                newline rule, you will get into
                                                           trouble.



  let flag = x is y;           // no n before 'is'!
  x ! p = v;                   // Q(x).put(’p’, v)
is an infix?
infix




        http://inimino.org/~inimino/blog/javascript_semicolons
infix
 An infix is an operand that goes in between numbers
 instead of in front of, or after them.




          http://inimino.org/~inimino/blog/javascript_semicolons
infix
 An infix is an operand that goes in between numbers
 instead of in front of, or after them.
   infix: 2 + 2
   prefix: + 2 2
   postfix: 2 2 +




          http://inimino.org/~inimino/blog/javascript_semicolons
infix
 An infix is an operand that goes in between numbers
 instead of in front of, or after them.
    infix: 2 + 2
    prefix: + 2 2
    postfix: 2 2 +

 Infix is much more difficult for machines to parse, but it
 is done so for the sake of human familiarity




           http://inimino.org/~inimino/blog/javascript_semicolons
infix
 An infix is an operand that goes in between numbers
 instead of in front of, or after them.
    infix: 2 + 2
    prefix: + 2 2
    postfix: 2 2 +

 Infix is much more difficult for machines to parse, but it
 is done so for the sake of human familiarity


 var foo = 'asdf'




           http://inimino.org/~inimino/blog/javascript_semicolons
infix
 An infix is an operand that goes in between numbers
 instead of in front of, or after them.
    infix: 2 + 2
    prefix: + 2 2
    postfix: 2 2 +

 Infix is much more difficult for machines to parse, but it
 is done so for the sake of human familiarity


 var foo = 'asdf'

[1,2,3].forEach(function(n){log(n)})



           http://inimino.org/~inimino/blog/javascript_semicolons
Conclusion
Conclusion
Conclusion
Conclusion
        David Flanagan's JS Definitive Guide on semi-
        colons: "Omitting semi-colons is not good
        programming practice; you should get in the
        habit of using them."
Conclusion
        David Flanagan's JS Definitive Guide on semi-
        colons: "Omitting semi-colons is not good
        programming practice; you should get in the
        habit of using them."

        Brendan Eich designed newline-terminators quite
        consciously, and they will not break in strict-
        mode (I've tested that).
Conclusion
        David Flanagan's JS Definitive Guide on semi-
        colons: "Omitting semi-colons is not good
        programming practice; you should get in the
        habit of using them."

        Brendan Eich designed newline-terminators quite
        consciously, and they will not break in strict-
        mode (I've tested that).

        Don't forget, there are plenty of places where
        you are *not* supposed to use a semicolon. So
        really, it's ultimately a matter of understanding
        the rules.
The Great Semicolon Debate

More Related Content

Similar to The Great Semicolon Debate

Python Compiler Internals Presentation Slides
Python Compiler Internals Presentation SlidesPython Compiler Internals Presentation Slides
Python Compiler Internals Presentation Slides
Tom Lee
 
The top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebasesThe top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebases
Phil Nash
 
Case, Loop & Command line args un Unix
Case, Loop & Command line args un UnixCase, Loop & Command line args un Unix
Case, Loop & Command line args un Unix
Vpmv
 
An SEO’s Intro to Web Dev PHP
An SEO’s Intro to Web Dev PHPAn SEO’s Intro to Web Dev PHP
An SEO’s Intro to Web Dev PHP
Troyfawkes
 
Douglas Crockford - Programming Style and Your Brain
Douglas Crockford - Programming Style and Your BrainDouglas Crockford - Programming Style and Your Brain
Douglas Crockford - Programming Style and Your Brain
Web Directions
 
A Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert FornalA Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert Fornal
QA or the Highway
 
Streams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetupStreams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetup
Brian Cardiff
 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
Philip Schwarz
 
Experiments in Reasoning
Experiments in ReasoningExperiments in Reasoning
Experiments in Reasoning
Aslam Khan
 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
Philip Schwarz
 
Spring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good partsSpring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good parts
Jarek Ratajski
 
DIWE - Programming with JavaScript
DIWE - Programming with JavaScriptDIWE - Programming with JavaScript
DIWE - Programming with JavaScript
Rasan Samarasinghe
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdf
ranjanadeore1
 
Goodparts
GoodpartsGoodparts
Goodparts
damonjablons
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
David Furber
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes
Tzach Zohar
 
The Java Script Programming Language
The  Java Script  Programming  LanguageThe  Java Script  Programming  Language
The Java Script Programming Languagezone
 

Similar to The Great Semicolon Debate (20)

ACM init() Day 2
ACM init() Day 2ACM init() Day 2
ACM init() Day 2
 
Python Compiler Internals Presentation Slides
Python Compiler Internals Presentation SlidesPython Compiler Internals Presentation Slides
Python Compiler Internals Presentation Slides
 
Vb script tutorial
Vb script tutorialVb script tutorial
Vb script tutorial
 
The top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebasesThe top 5 JavaScript issues in all our codebases
The top 5 JavaScript issues in all our codebases
 
Case, Loop & Command line args un Unix
Case, Loop & Command line args un UnixCase, Loop & Command line args un Unix
Case, Loop & Command line args un Unix
 
An SEO’s Intro to Web Dev PHP
An SEO’s Intro to Web Dev PHPAn SEO’s Intro to Web Dev PHP
An SEO’s Intro to Web Dev PHP
 
Douglas Crockford - Programming Style and Your Brain
Douglas Crockford - Programming Style and Your BrainDouglas Crockford - Programming Style and Your Brain
Douglas Crockford - Programming Style and Your Brain
 
A Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert FornalA Lifecycle Of Code Under Test by Robert Fornal
A Lifecycle Of Code Under Test by Robert Fornal
 
Streams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetupStreams of information - Chicago crystal language monthly meetup
Streams of information - Chicago crystal language monthly meetup
 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
 
Experiments in Reasoning
Experiments in ReasoningExperiments in Reasoning
Experiments in Reasoning
 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
 
Spring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good partsSpring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good parts
 
Vb script tutorial
Vb script tutorialVb script tutorial
Vb script tutorial
 
DIWE - Programming with JavaScript
DIWE - Programming with JavaScriptDIWE - Programming with JavaScript
DIWE - Programming with JavaScript
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdf
 
Goodparts
GoodpartsGoodparts
Goodparts
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes
 
The Java Script Programming Language
The  Java Script  Programming  LanguageThe  Java Script  Programming  Language
The Java Script Programming Language
 

More from Mike Wilcox

Accessibility for Fun and Profit
Accessibility for Fun and ProfitAccessibility for Fun and Profit
Accessibility for Fun and Profit
Mike Wilcox
 
WTF R PWAs?
WTF R PWAs?WTF R PWAs?
WTF R PWAs?
Mike Wilcox
 
Advanced React
Advanced ReactAdvanced React
Advanced React
Mike Wilcox
 
Webpack: What it is, What it does, Whether you need it
Webpack: What it is, What it does, Whether you need itWebpack: What it is, What it does, Whether you need it
Webpack: What it is, What it does, Whether you need it
Mike Wilcox
 
Dangerous CSS
Dangerous CSSDangerous CSS
Dangerous CSS
Mike Wilcox
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
Mike Wilcox
 
Great Responsive-ability Web Design
Great Responsive-ability Web DesignGreat Responsive-ability Web Design
Great Responsive-ability Web Design
Mike Wilcox
 
Professional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsProfessional JavaScript: AntiPatterns
Professional JavaScript: AntiPatterns
Mike Wilcox
 
Model View Madness
Model View MadnessModel View Madness
Model View Madness
Mike Wilcox
 
Hardcore JavaScript – Write it Right
Hardcore JavaScript – Write it RightHardcore JavaScript – Write it Right
Hardcore JavaScript – Write it Right
Mike Wilcox
 
AMD - Why, What and How
AMD - Why, What and HowAMD - Why, What and How
AMD - Why, What and How
Mike Wilcox
 
Dojo & HTML5
Dojo & HTML5Dojo & HTML5
Dojo & HTML5
Mike Wilcox
 
Webpage Design Basics for Non-Designers
Webpage Design Basics for Non-DesignersWebpage Design Basics for Non-Designers
Webpage Design Basics for Non-DesignersMike Wilcox
 
Why You Need a Front End Developer
Why You Need a Front End DeveloperWhy You Need a Front End Developer
Why You Need a Front End Developer
Mike Wilcox
 
A Conversation About REST
A Conversation About RESTA Conversation About REST
A Conversation About REST
Mike Wilcox
 
The Fight Over HTML5
The Fight Over HTML5The Fight Over HTML5
The Fight Over HTML5
Mike Wilcox
 
The Fight Over HTML5
The Fight Over HTML5The Fight Over HTML5
The Fight Over HTML5
Mike Wilcox
 
How to get a Job as a Front End Developer
How to get a Job as a Front End DeveloperHow to get a Job as a Front End Developer
How to get a Job as a Front End Developer
Mike Wilcox
 
The History of HTML5
The History of HTML5The History of HTML5
The History of HTML5
Mike Wilcox
 
Thats Not Flash?
Thats Not Flash?Thats Not Flash?
Thats Not Flash?
Mike Wilcox
 

More from Mike Wilcox (20)

Accessibility for Fun and Profit
Accessibility for Fun and ProfitAccessibility for Fun and Profit
Accessibility for Fun and Profit
 
WTF R PWAs?
WTF R PWAs?WTF R PWAs?
WTF R PWAs?
 
Advanced React
Advanced ReactAdvanced React
Advanced React
 
Webpack: What it is, What it does, Whether you need it
Webpack: What it is, What it does, Whether you need itWebpack: What it is, What it does, Whether you need it
Webpack: What it is, What it does, Whether you need it
 
Dangerous CSS
Dangerous CSSDangerous CSS
Dangerous CSS
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Great Responsive-ability Web Design
Great Responsive-ability Web DesignGreat Responsive-ability Web Design
Great Responsive-ability Web Design
 
Professional JavaScript: AntiPatterns
Professional JavaScript: AntiPatternsProfessional JavaScript: AntiPatterns
Professional JavaScript: AntiPatterns
 
Model View Madness
Model View MadnessModel View Madness
Model View Madness
 
Hardcore JavaScript – Write it Right
Hardcore JavaScript – Write it RightHardcore JavaScript – Write it Right
Hardcore JavaScript – Write it Right
 
AMD - Why, What and How
AMD - Why, What and HowAMD - Why, What and How
AMD - Why, What and How
 
Dojo & HTML5
Dojo & HTML5Dojo & HTML5
Dojo & HTML5
 
Webpage Design Basics for Non-Designers
Webpage Design Basics for Non-DesignersWebpage Design Basics for Non-Designers
Webpage Design Basics for Non-Designers
 
Why You Need a Front End Developer
Why You Need a Front End DeveloperWhy You Need a Front End Developer
Why You Need a Front End Developer
 
A Conversation About REST
A Conversation About RESTA Conversation About REST
A Conversation About REST
 
The Fight Over HTML5
The Fight Over HTML5The Fight Over HTML5
The Fight Over HTML5
 
The Fight Over HTML5
The Fight Over HTML5The Fight Over HTML5
The Fight Over HTML5
 
How to get a Job as a Front End Developer
How to get a Job as a Front End DeveloperHow to get a Job as a Front End Developer
How to get a Job as a Front End Developer
 
The History of HTML5
The History of HTML5The History of HTML5
The History of HTML5
 
Thats Not Flash?
Thats Not Flash?Thats Not Flash?
Thats Not Flash?
 

Recently uploaded

Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 

Recently uploaded (20)

Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 

The Great Semicolon Debate

  • 2. The Great Semicolon Debate By Mike Wilcox May 2012
  • 3. or how the semicolon may bring down society By Mike Wilcox May 2012
  • 5. What does a semicolon look like?
  • 6. What does a semicolon look like?
  • 7. What does a semicolon look like?
  • 8. What does a semicolon look like?
  • 9. What does a semicolon look like? ~ ~ !
  • 10. What does a semicolon look like? ~ ~ !
  • 11. What does a semicolon look like? ~ ~ !
  • 15. In Other Languages English: ; French: ; Spanish: ;
  • 16. In Other Languages English: ; French: ; Spanish: ; Wingdings 1: 
  • 17. In Other Languages English: ; French: ; Spanish: ; Wingdings 1:  Wingdings 2: 
  • 19. In Code In CSS: Semicolons are REQUIRED
  • 20. In Code In CSS: Semicolons are REQUIRED background:#ff0000;
  • 21. In Code In CSS: Semicolons are REQUIRED background:#ff0000; In HTML: Semicolons are NOT USED
  • 22. In Code In CSS: Semicolons are REQUIRED background:#ff0000; In HTML: Semicolons are NOT USED <div class=”awesomeness”>bob</div>
  • 23. In Code In CSS: Semicolons are REQUIRED background:#ff0000; In HTML: Semicolons are NOT USED <div class=”awesomeness”>bob</div> In JavaScript: Semicolons are... OPTIONAL
  • 24. In Code In CSS: Semicolons are REQUIRED background:#ff0000; In HTML: Semicolons are NOT USED <div class=”awesomeness”>bob</div> In JavaScript: Semicolons are... OPTIONAL Hence, the CONTROVERSY!
  • 26. Example Is this correct? var test = function(){ ! console.log('Hello World') }
  • 27. Example Is this correct? var test = function(){ ! console.log('Hello World') } Or this? var test = function(){ ! console.log('Hello World'); };
  • 28. Example Is this correct? var test = function(){ ! console.log('Hello World') } Or this? var test = function(){ ! console.log('Hello World'); }; Answer: both!
  • 29. ASI
  • 31. ASI Automatic Semicolon Insertion Certain ECMAScript statements (empty statement, variable statement, expression statement, do-while statement, continue statement, break statement, return statement, and throw statement) must be terminated with semicolons.
  • 32. ASI Automatic Semicolon Insertion Certain ECMAScript statements (empty statement, variable statement, expression statement, do-while statement, continue statement, break statement, return statement, and throw statement) must be terminated with semicolons. For convenience, however, such semicolons may be omitted from the source text in certain situations.
  • 33. ASI Automatic Semicolon Insertion Certain ECMAScript statements (empty statement, variable statement, expression statement, do-while statement, continue statement, break statement, return statement, and throw statement) must be terminated with semicolons. For convenience, however, such semicolons may be omitted from the source text in certain situations. These situations are described by saying that semicolons are automatically inserted into the source code token stream in those situations.
  • 34.
  • 35. Uh, no. I really didn’t get that.
  • 36. ASI (simplified)
  • 37. ASI (simplified) Automatic Semicolon Insertion
  • 38. ASI (simplified) Automatic Semicolon Insertion Other than continue, break, return, and throw, JavaScript will consider a newline to be the end of your expression.
  • 40. ASI Examples var foo = 3 var bar = “foo” var myObject = { a:1, b:2 } doSomething() while(a < 1){ b++ } return buzz
  • 41. ASI Examples var foo = 3 var bar = “foo” var myObject = { a:1, b:2 } doSomething() while(a < 1){ b++ } return buzz No semicolons needed!
  • 42.
  • 47. ASI Examples Does this work? var foo = 1+2 ('bob' + 'guru').toUpperCase()
  • 48. ASI Examples Does this work? var foo = 1+2 ('bob' + 'guru').toUpperCase() ERROR: number is not a function
  • 49. ASI Examples Does this work? var foo = 1+2 ('bob' + 'guru').toUpperCase() ERROR: number is not a function JavaScript sees that code like this:
  • 50. ASI Examples Does this work? var foo = 1+2 ('bob' + 'guru').toUpperCase() ERROR: number is not a function JavaScript sees that code like this: var foo = 1+2('bob' + 'guru').toUpperCase();
  • 51.
  • 52. Uhhh... I thought you said JavaScript will consider a newline to be the end of your expression.
  • 53. ASI
  • 54. ASI A semicolon is not implied at the end of a line if the first token of the subsequent line can be parsed as part of the same statement.
  • 55. ASI A semicolon is not implied at the end of a line if the first token of the subsequent line can be parsed as part of the same statement. There are five tokens that can appear both at the start of a statement, and as an extension of a complete statement. These tokens are the open parenthesis ( open square brace [ slash or solidus /, and + and -.
  • 56. ASI A semicolon is not implied at the end of a line if the first token of the subsequent line can be parsed as part of the same statement. There are five tokens that can appear both at the start of a statement, and as an extension of a complete statement. These tokens are the open parenthesis ( open square brace [ slash or solidus /, and + and -. In particular, these will cause you problems: ( [
  • 59. ASI Examples Does this work? var foo = 'asdf' [1,2,3].forEach(function(n){log(n)})
  • 60. ASI Examples Does this work? var foo = 'asdf' [1,2,3].forEach(function(n){log(n)}) "asdf"[1, 2, 3].forEach is not a function
  • 61. ASI Examples Does this work? var foo = 'asdf' [1,2,3].forEach(function(n){log(n)}) "asdf"[1, 2, 3].forEach is not a function What’s wrong with this?
  • 62. ASI Examples Does this work? var foo = 'asdf' [1,2,3].forEach(function(n){log(n)}) "asdf"[1, 2, 3].forEach is not a function What’s wrong with this? i=0 /[a-z]/g.exec(s)
  • 63. ASI Examples Does this work? var foo = 'asdf' [1,2,3].forEach(function(n){log(n)}) "asdf"[1, 2, 3].forEach is not a function What’s wrong with this? i=0 /[a-z]/g.exec(s) a is not defined
  • 65. ASI Examples What does this return?
  • 66. ASI Examples What does this return? return 1 + 2
  • 67. ASI Examples What does this return? return 1 + 2 undefined
  • 68. ASI Examples What does this return? return 1 + 2 undefined Remember, continue, break, return, and throw are exceptions and must end with a semicolon. ASI is not used.
  • 69. ASI Examples What does this return? return 1 + 2 undefined Remember, continue, break, return, and throw are exceptions and must end with a semicolon. ASI is not used. return( 1 + 2 )
  • 70. ASI Examples What does this return? return 1 + 2 undefined Remember, continue, break, return, and throw are exceptions and must end with a semicolon. ASI is not used. return( 1 + 2 ) This works.
  • 72. Newbie does what You might think the solution is to add a semicolon to the end of every line...
  • 73. Newbie does what You might think the solution is to add a semicolon to the end of every line... if(true){ doSomething(); }; function doBob(){ return “do not”; };
  • 74. Newbie does what You might think the solution is to add a semicolon to the end of every line... if(true){ doSomething(); }; function doBob(){ return “do not”; }; Not an error! But... JSLint says: “unexpected semicolon.”
  • 75. Newbie does what You might think the solution is to add a semicolon to the end of every line... if(true){ If yo u put doSomething(); o ne }; here... there ’s no function doBob(){ helping yo u r return “do not”; }; cause. Not an error! But... JSLint says: “unexpected semicolon.”
  • 76. No ASI to see here
  • 77. No ASI to see here Semicolons should not be used for block statements.
  • 78. No ASI to see here Semicolons should not be used for block statements. if(true){ doSomething(); } function doBob(){ return “do not”; } while(true){ doBob(); } for(var ba=0; ba<beer.left; ba++){ drink++; }
  • 79.
  • 82. The Trigger https://github.com/twitter/bootstrap/issues/3057
  • 83. The Trigger clearMenus() !isActive && $parent.toggleClass(‘open’) https://github.com/twitter/bootstrap/issues/3057
  • 87. The Battle on Github
  • 88. The Battle on Github
  • 89. The Battle on Github
  • 90. The Battle on Github
  • 91. The Battle on Github
  • 92. The Battle on Github
  • 93. The Battle on Github
  • 94. The Battle on Github
  • 95. The Battle on Github
  • 96. The Battle on Github
  • 97. The Battle on Github
  • 98. The Battle on Github
  • 99. The Battle on Github
  • 100. The Battle on Github
  • 101. The Battle on Github
  • 102. The Battle on LinkedIn
  • 103. The Battle on LinkedIn
  • 104. The Battle on LinkedIn
  • 105. The Battle on LinkedIn
  • 106. The Battle on LinkedIn
  • 109. Library Solution Tho mas Fu chs, author of Scriptaculo us
  • 110. Library Solution Tho mas Fu chs, author of Scriptaculo us
  • 120. Brendan Makes it Clear.
  • 121. Brendan Makes it Clear. Most of the comments in the semicolons exchange make me sad.
  • 122. Brendan Makes it Clear. Most of the comments in In the proposed promises the semicolons exchange make grammar and you’ll see something me sad. surprising about ASI and infix operators: we can add new infix operators in the future.
  • 123. Brendan Makes it Clear. Most of the comments in In the proposed promises the semicolons exchange make grammar and you’ll see something me sad. surprising about ASI and infix operators: we can add new infix operators in the future. let flag = x is y; // no n before 'is'! x ! p = v; // Q(x).put(’p’, v)
  • 124. Brendan Makes it Clear. Most of the comments in In the proposed promises the semicolons exchange make grammar and you’ll see something me sad. surprising about ASI and infix operators: we can add new infix operators in the future. The moral of this story: ASI is (formally speaking) a syntactic error correction procedure. If you start to code as if it were a universal significant- newline rule, you will get into trouble. let flag = x is y; // no n before 'is'! x ! p = v; // Q(x).put(’p’, v)
  • 125.
  • 127. infix http://inimino.org/~inimino/blog/javascript_semicolons
  • 128. infix An infix is an operand that goes in between numbers instead of in front of, or after them. http://inimino.org/~inimino/blog/javascript_semicolons
  • 129. infix An infix is an operand that goes in between numbers instead of in front of, or after them. infix: 2 + 2 prefix: + 2 2 postfix: 2 2 + http://inimino.org/~inimino/blog/javascript_semicolons
  • 130. infix An infix is an operand that goes in between numbers instead of in front of, or after them. infix: 2 + 2 prefix: + 2 2 postfix: 2 2 + Infix is much more difficult for machines to parse, but it is done so for the sake of human familiarity http://inimino.org/~inimino/blog/javascript_semicolons
  • 131. infix An infix is an operand that goes in between numbers instead of in front of, or after them. infix: 2 + 2 prefix: + 2 2 postfix: 2 2 + Infix is much more difficult for machines to parse, but it is done so for the sake of human familiarity var foo = 'asdf' http://inimino.org/~inimino/blog/javascript_semicolons
  • 132. infix An infix is an operand that goes in between numbers instead of in front of, or after them. infix: 2 + 2 prefix: + 2 2 postfix: 2 2 + Infix is much more difficult for machines to parse, but it is done so for the sake of human familiarity var foo = 'asdf' [1,2,3].forEach(function(n){log(n)}) http://inimino.org/~inimino/blog/javascript_semicolons
  • 136. Conclusion David Flanagan's JS Definitive Guide on semi- colons: "Omitting semi-colons is not good programming practice; you should get in the habit of using them."
  • 137. Conclusion David Flanagan's JS Definitive Guide on semi- colons: "Omitting semi-colons is not good programming practice; you should get in the habit of using them." Brendan Eich designed newline-terminators quite consciously, and they will not break in strict- mode (I've tested that).
  • 138. Conclusion David Flanagan's JS Definitive Guide on semi- colons: "Omitting semi-colons is not good programming practice; you should get in the habit of using them." Brendan Eich designed newline-terminators quite consciously, and they will not break in strict- mode (I've tested that). Don't forget, there are plenty of places where you are *not* supposed to use a semicolon. So really, it's ultimately a matter of understanding the rules.

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n