<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: hudson-newey</title>
    <description>The latest articles on Forem by hudson-newey (@hudsonnewey).</description>
    <link>https://forem.com/hudsonnewey</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1028490%2Fcd670d76-cd4f-4acb-a2de-fb83f5a4fd11.png</url>
      <title>Forem: hudson-newey</title>
      <link>https://forem.com/hudsonnewey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hudsonnewey"/>
    <language>en</language>
    <item>
      <title>A Case for Semicolon-less JavaScript (ASI)</title>
      <dc:creator>hudson-newey</dc:creator>
      <pubDate>Sat, 31 May 2025 13:18:26 +0000</pubDate>
      <link>https://forem.com/hudsonnewey/why-javascript-semicolons-need-to-die-a-case-for-asi-5cca</link>
      <guid>https://forem.com/hudsonnewey/why-javascript-semicolons-need-to-die-a-case-for-asi-5cca</guid>
      <description>&lt;h2&gt;
  
  
  Why semi-columns
&lt;/h2&gt;

&lt;p&gt;Before making a case for semicolon-less JavaScript, you must first understand why the majority of experienced developers will continue to reject automatic semicolon insertion (ASI). Why these seemingly experienced developers clutter their code and keystrokes.&lt;/p&gt;

&lt;p&gt;In short semi-columns in JavaScript helps reduce the surface for bugs in poorly maintained code bases, and provides clearer intent to formatters such as &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;prettier&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The case for semicolon-less JavaScript
&lt;/h2&gt;

&lt;p&gt;I spent a long time searching for reasons for and against JavaScript semi-columns. But almost all of the reasons against semi-columns were "linting should catch semicolon-less errors" and "I can type at 100 words per minute, so if I omit a semi column, I can save 0.6 seconds per line", or the worst "it looks better".&lt;/p&gt;

&lt;p&gt;However, I have recently come across a &lt;strong&gt;stronger&lt;/strong&gt; argument for semicolon-less JavaScript and ASI.&lt;/p&gt;

&lt;h3&gt;
  
  
  DIFFS AND BLAMES
&lt;/h3&gt;

&lt;p&gt;I believe that one of the quickest ways to determine the quality of a code base is to look at the Git / version control history.&lt;/p&gt;

&lt;p&gt;A good commit history is descriptive, has clear ownership, and has a well maintained blame. A well maintained blame and version history is often overlooked by the majority of developers, but correct version control is more descriptive than any number of code comments. Each commit is a snapshot that describes who made a change, why they made the change, and what problem they were trying to fix.&lt;/p&gt;

&lt;p&gt;Additionally, a good diff is important for code reviewers who will commonly review using a diff or patch view.&lt;/p&gt;

&lt;p&gt;However, semi-columns do not play nicely with the &lt;a href="https://en.wikipedia.org/wiki/Builder_pattern" rel="noopener noreferrer"&gt;builder pattern&lt;/a&gt; or functional programming paradigms.&lt;/p&gt;

&lt;p&gt;While you may not like either the builder pattern of functional programming, your project will inevitably use code someone else has written. And that person may not agree with your reservations.&lt;/p&gt;

&lt;p&gt;For a simple demonstration, I have created a simple class that has two methods, &lt;code&gt;add()&lt;/code&gt; and &lt;code&gt;sub()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyBasicMath&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyBasicMath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my contrived universe, I have recently found a bug in my code, &lt;code&gt;myValue&lt;/code&gt; is currently wrong because I forgot to add three. So a simple fix will be to append another &lt;code&gt;.add(3)&lt;/code&gt; to the end of this function chain.&lt;/p&gt;

&lt;p&gt;I have provided two diff's below, the first one is an example adding a &lt;code&gt;add(3)&lt;/code&gt; call to a code base that uses semi-columns, while the second example is semicolon-less.&lt;/p&gt;

&lt;p&gt;In the project that uses semi-columns you'll see that if I append a &lt;code&gt;sub()&lt;/code&gt; method call, the line above is also included in the diff because the semi-column was removed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Diff with semi columns&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const myValue = new MyBasicMath()
&lt;/span&gt;    .add(5)
&lt;span class="gd"&gt;-   .sub(1);
&lt;/span&gt;&lt;span class="gi"&gt;+   .sub(1)
+   .add(3);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Diff without semi columns&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const myValue = new MyBasicMath()
&lt;/span&gt;    .add(5)
    .sub(1)
&lt;span class="gi"&gt;+   .add(3)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see above, I am being blamed for the &lt;code&gt;sub&lt;/code&gt; function. When the real change that I made was adding &lt;code&gt;add(-3)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A more common/relatable example would be functional programming paradigms such as the &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, etc... Array &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods" rel="noopener noreferrer"&gt;instance methods&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;myData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I was to add an additional &lt;code&gt;map&lt;/code&gt; function to the end of this method chain, the usefulness of the Git blame would immediately be destroyed because I would be blamed for changing the &lt;code&gt;filter&lt;/code&gt; line when the semi-column was removed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const myData = [-2,-1,0,1,2];
const result =
&lt;/span&gt;  myData.map((value) =&amp;gt; value * 2)
&lt;span class="gd"&gt;-    .filter(() =&amp;gt; value &amp;gt; 0);
&lt;/span&gt;&lt;span class="gi"&gt;+    .filter(() =&amp;gt; value &amp;gt; 0)
+    .map((value) =&amp;gt; value + 1);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>git</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
