JS++
Web programming language
- 16 min read
- 4 chapters
- 1 lab on Lably
Learn it on Lably
History
JS++ first appeared on October 8, 2011. The modern implementation was announced at DeveloperWeek 2016 and released on May 31, 2016. The language is designed by Roger Poon and Anton Rapetov.
Sign in to keep reading
3 more chapters are free with a Lably account.
Features
Sound gradual type system
Since JS++ is a superset of JavaScript, declaring data types for variables is optional. However, when types are declared, the types are enforced at both compile time and runtime.
Type annotations in JS++ use the traditional C/C++ syntax:
<span id="mwPw"></span><span class="kt" id="mwQA">int</span><span class="w" id="mwQQ"> </span><span class="n" id="mwQg">x</span><span class="w" id="mwQw"> </span><span class="o" id="mwRA">=</span><span class="w" id="mwRQ"> </span><span class="mi" id="mwRg">1</span><span class="p" id="mwRw">;</span> <span class="kt" id="mwSA">var</span><span class="w" id="mwSQ"> </span><span class="n" id="mwSg">y</span><span class="w" id="mwSw"> </span><span class="o" id="mwTA">=</span><span class="w" id="mwTQ"> </span><span class="mi" id="mwTg">2</span><span class="p" id="mwTw">;</span> <span class="kt" id="mwUA">bool</span><span class="w" id="mwUQ"> </span><span class="n" id="mwUg">z</span><span class="w" id="mwUw"> </span><span class="o" id="mwVA">=</span><span class="w" id="mwVQ"> </span><span class="k" id="mwVg">true</span><span class="p" id="mwVw">;</span>
Notably, this differs from TypeScript and ActionScript, which use a more verbose style:
<span id="mwXQ"></span><span class="kd" id="mwXg">let</span><span class="w" id="mwXw"> </span><span class="nx" id="mwYA">x</span><span class="o" id="mwYQ">:</span><span class="w" id="mwYg"> </span><span class="kt" id="mwYw">number</span><span class="w" id="mwZA"> </span><span class="o" id="mwZQ">=</span><span class="w" id="mwZg"> </span><span class="mf" id="mwZw">1</span><span class="p" id="mwaA">;</span> <span class="kd" id="mwaQ">let</span><span class="w" id="mwag"> </span><span class="nx" id="mwaw">y</span><span class="o" id="mwbA">:</span><span class="w" id="mwbQ"> </span><span class="kt" id="mwbg">any</span><span class="w" id="mwbw"> </span><span class="o" id="mwcA">=</span><span class="w" id="mwcQ"> </span><span class="mf" id="mwcg">2</span><span class="p" id="mwcw">;</span> <span class="kd" id="mwdA">let</span><span class="w" id="mwdQ"> </span><span class="nx" id="mwdg">z</span><span class="o" id="mwdw">:</span><span class="w" id="mweA"> </span><span class="kt" id="mweQ">boolean</span><span class="w" id="mweg"> </span><span class="o" id="mwew">=</span><span class="w" id="mwfA"> </span><span class="kc" id="mwfQ">true</span><span class="p" id="mwfg">;</span>
The type system in JS++ is sound for ECMAScript and DOM API corner cases, including host objects, dynamic key-value pairs, Comet, JScript conditional compilation, dynamic return types, ActiveX, ECMAScript for XML, web browser garbage collector and cyclic reference counting bugs, conditional logic, and other edge and corner cases. This differs from other JavaScript supersets where types are optional and discarded at runtime via type erasure, such as in TypeScript.
Importing JavaScript libraries
JS++ can use JavaScript libraries using the one-line external statement as in the following example from the homepage of JS++:
<span id="mwpw"></span><span class="k" id="mwqA">import</span><span class="w" id="mwqQ"> </span><span class="nx" id="mwqg">System</span><span class="p" id="mwqw">;</span> <span class="c1" id="mwrA">// Import JavaScript libraries in one line of code</span> <span class="nx" id="mwrQ">external</span><span class="w" id="mwrg"> </span><span class="nx" id="mwrw">jQuery</span><span class="p" id="mwsA">,</span><span class="w" id="mwsQ"> </span><span class="nx" id="mwsg">$</span><span class="p" id="mwsw">;</span> <span class="kd" id="mwtA">class</span><span class="w" id="mwtQ"> </span><span class="nx" id="mwtg">Example</span><span class="w" id="mwtw"> </span><span class="p" id="mwuA">{</span> <span class="w" id="mwuQ"> </span><span class="k" id="mwug">public</span><span class="w" id="mwuw"> </span><span class="nx" id="mwvA">Example</span><span class="p" id="mwvQ">()</span><span class="w" id="mwvg"> </span><span class="p" id="mwvw">{</span> <span class="w" id="mwwA"> </span><span class="c1" id="mwwQ">// Nearly NO learning curve</span> <span class="w" id="mwwg"> </span><span class="c1" id="mwww">// You can keep writing regular JavaScript</span> <span class="w" id="mwxA"> </span><span class="kd" id="mwxQ">var</span><span class="w" id="mwxg"> </span><span class="nx" id="mwxw">a</span><span class="w" id="mwyA"> </span><span class="o" id="mwyQ">=</span><span class="w" id="mwyg"> </span><span class="mf" id="mwyw">0</span><span class="p" id="mwzA">,</span><span class="w" id="mwzQ"> </span><span class="nx" id="mwzg">random</span><span class="w" id="mwzw"> </span><span class="o" id="mw0A">=</span><span class="w" id="mw0Q"> </span><span class="nb" id="mw0g">Math</span><span class="p" id="mw0w">.</span><span class="nx" id="mw1A">random</span><span class="p" id="mw1Q">();</span> <span class="w" id="mw1g"> </span><span class="c1" id="mw1w">// Integer types and other primitives</span> <span class="w" id="mw2A"> </span><span class="c1" id="mw2Q">// ... enable fast (optimized) and clear code</span> <span class="w" id="mw2g"> </span><span class="kr" id="mw2w">byte</span><span class="p" id="mw3A">[]</span><span class="w" id="mw3Q"> </span><span class="nx" id="mw3g">rgbColors</span><span class="w" id="mw3w"> </span><span class="o" id="mw4A">=</span><span class="w" id="mw4Q"> </span><span class="p" id="mw4g">[</span><span class="mh" id="mw4w">0xFF</span><span class="p" id="mw5A">,</span><span class="w" id="mw5Q"> </span><span class="mh" id="mw5g">0xFA</span><span class="p" id="mw5w">,</span><span class="w" id="mw6A"> </span><span class="mh" id="mw6Q">0xFF</span><span class="p" id="mw6g">];</span> <span class="w" id="mw6w"> </span><span class="p" id="mw7A">}</span> <span class="w" id="mw7Q"> </span><span class="k" id="mw7g">public</span><span class="w" id="mw7w"> </span><span class="ow" id="mw8A">void</span><span class="w" id="mw8Q"> </span><span class="nx" id="mw8g">showMessage</span><span class="p" id="mw8w">(</span><span class="kr" id="mw9A">int</span><span class="w" id="mw9Q"> </span><span class="nx" id="mw9g">id</span><span class="p" id="mw9w">,</span><span class="w" id="mw-A"> </span><span class="kt" id="mw-Q">string</span><span class="w" id="mw-g"> </span><span class="nx" id="mw-w">text</span><span class="p" id="mw_A">)</span><span class="w" id="mw_Q"> </span><span class="p" id="mw_g">{</span> <span class="w" id="mw_w"> </span><span class="c1" id="mwAQA">// 100% compatible with regular JavaScript</span> <span class="w" id="mwAQE"> </span><span class="nx" id="mwAQI">jQuery</span><span class="p" id="mwAQM">(</span><span class="s2" id="mwAQQ">"#msgbox"</span><span class="p" id="mwAQU">).</span><span class="nx" id="mwAQY">show</span><span class="p" id="mwAQc">();</span> <span class="w" id="mwAQg"> </span><span class="nx" id="mwAQk">$</span><span class="p" id="mwAQo">(</span><span class="s2" id="mwAQs">"#msgbox"</span><span class="p" id="mwAQw">).</span><span class="nx" id="mwAQ0">text</span><span class="p" id="mwAQ4">(</span><span class="nx" id="mwAQ8">id</span><span class="p" id="mwARA">.</span><span class="nx" id="mwARE">toString</span><span class="p" id="mwARI">()</span><span class="w" id="mwARM"> </span><span class="o" id="mwARQ">+</span><span class="w" id="mwARU"> </span><span class="nx" id="mwARY">text</span><span class="p" id="mwARc">);</span> <span class="w" id="mwARg"> </span><span class="p" id="mwARk">}</span> <span class="p" id="mwARo">}</span>Object-oriented programming
While classes in JavaScript (ECMAScript 6) are syntactic sugar for prototypes under the hood, JS++ classes resemble the classes found in classical programming languages such as C++, Java, and C# in terms of memory layout, performance, and semantics. "Classes" are a static concept, and they cannot be altered at runtime (during program execution) as is the case for JavaScript, Smalltalk, Lisp, and TypeScript, which rely on prototypes. For example, private methods are private at both compile time and runtime, and external JavaScript objects cannot access private JS++ fields or methods—even if a reference to a JS++ object is obtained from JavaScript.
Example: object-oriented sorting
The following source code illustrates object-oriented sorting in JS++ using the System.IComparable<T> interface and System.Comparison enumeration for type-safe and readable comparisons. The custom sorting logic is one line of code in the overridden compare() method below:
<span id="mwAUA"></span><span class="k" id="mwAUE">import</span><span class="w" id="mwAUI"> </span><span class="nx" id="mwAUM">System</span><span class="p" id="mwAUQ">;</span> <span class="w" id="mwAUU"> </span> <span class="kd" id="mwAUY">class</span><span class="w" id="mwAUc"> </span><span class="nx" id="mwAUg">Employee</span><span class="w" id="mwAUk"> </span><span class="o" id="mwAUo">:</span><span class="w" id="mwAUs"> </span><span class="kt" id="mwAUw">IComparable</span><span class="o" id="mwAU0"><</span><span class="nx" id="mwAU4">Employee</span><span class="o" id="mwAU8">></span><span class="w" id="mwAVA"> </span><span class="p" id="mwAVE">{</span> <span class="w" id="mwAVI"> </span><span class="k" id="mwAVM">private</span><span class="w" id="mwAVQ"> </span><span class="kt" id="mwAVU">string</span><span class="w" id="mwAVY"> </span><span class="nx" id="mwAVc">firstName</span><span class="p" id="mwAVg">;</span> <span class="w" id="mwAVk"> </span><span class="k" id="mwAVo">private</span><span class="w" id="mwAVs"> </span><span class="kt" id="mwAVw">string</span><span class="w" id="mwAV0"> </span><span class="nx" id="mwAV4">lastName</span><span class="p" id="mwAV8">;</span> <span class="w" id="mwAWA"> </span> <span class="w" id="mwAWE"> </span><span class="k" id="mwAWI">public</span><span class="w" id="mwAWM"> </span><span class="nx" id="mwAWQ">Employee</span><span class="p" id="mwAWU">(</span><span class="kt" id="mwAWY">string</span><span class="w" id="mwAWc"> </span><span class="nx" id="mwAWg">firstName</span><span class="p" id="mwAWk">,</span><span class="w" id="mwAWo"> </span><span class="kt" id="mwAWs">string</span><span class="w" id="mwAWw"> </span><span class="nx" id="mwAW0">lastName</span><span class="p" id="mwAW4">)</span><span class="w" id="mwAW8"> </span><span class="p" id="mwAXA">{</span> <span class="w" id="mwAXE"> </span><span class="k" id="mwAXI">this</span><span class="p" id="mwAXM">.</span><span class="nx" id="mwAXQ">firstName</span><span class="w" id="mwAXU"> </span><span class="o" id="mwAXY">=</span><span class="w" id="mwAXc"> </span><span class="nx" id="mwAXg">firstName</span><span class="p" id="mwAXk">;</span> <span class="w" id="mwAXo"> </span><span class="k" id="mwAXs">this</span><span class="p" id="mwAXw">.</span><span class="nx" id="mwAX0">lastName</span><span class="w" id="mwAX4"> </span><span class="o" id="mwAX8">=</span><span class="w" id="mwAYA"> </span><span class="nx" id="mwAYE">lastName</span><span class="p" id="mwAYI">;</span> <span class="w" id="mwAYM"> </span><span class="p" id="mwAYQ">}</span> <span class="w" id="mwAYU"> </span> <span class="w" id="mwAYY"> </span><span class="k" id="mwAYc">public</span><span class="w" id="mwAYg"> </span><span class="kd" id="mwAYk">override</span><span class="w" id="mwAYo"> </span><span class="nx" id="mwAYs">Comparison</span><span class="w" id="mwAYw"> </span><span class="nx" id="mwAY0">compare</span><span class="p" id="mwAY4">(</span><span class="nx" id="mwAY8">Employee</span><span class="w" id="mwAZA"> </span><span class="nx" id="mwAZE">that</span><span class="p" id="mwAZI">)</span><span class="w" id="mwAZM"> </span><span class="p" id="mwAZQ">{</span> <span class="w" id="mwAZU"> </span><span class="c1" id="mwAZY">// Sort by employee surname</span> <span class="hll" id="mwAZc"><span class="w" id="mwAZg"> </span><span class="k" id="mwAZk">return</span><span class="w" id="mwAZo"> </span><span class="k" id="mwAZs">this</span><span class="p" id="mwAZw">.</span><span class="nx" id="mwAZ0">lastName</span><span class="p" id="mwAZ4">.</span><span class="nx" id="mwAZ8">compare</span><span class="p" id="mwAaA">(</span><span class="nx" id="mwAaE">that</span><span class="p" id="mwAaI">.</span><span class="nx" id="mwAaM">lastName</span><span class="p" id="mwAaQ">);</span> </span><span class="w" id="mwAaU"> </span><span class="p" id="mwAaY">}</span> <span class="w" id="mwAac"> </span> <span class="w" id="mwAag"> </span><span class="k" id="mwAak">public</span><span class="w" id="mwAao"> </span><span class="kd" id="mwAas">override</span><span class="w" id="mwAaw"> </span><span class="kt" id="mwAa0">string</span><span class="w" id="mwAa4"> </span><span class="nx" id="mwAa8">toString</span><span class="p" id="mwAbA">()</span><span class="w" id="mwAbE"> </span><span class="p" id="mwAbI">{</span> <span class="w" id="mwAbM"> </span><span class="k" id="mwAbQ">return</span><span class="w" id="mwAbU"> </span><span class="sb" id="mwAbY">`</span><span class="si" id="mwAbc">${</span><span class="k" id="mwAbg">this</span><span class="p" id="mwAbk">.</span><span class="nx" id="mwAbo">firstName</span><span class="si" id="mwAbs">}</span><span class="sb" id="mwAbw"> </span><span class="si" id="mwAb0">${</span><span class="k" id="mwAb4">this</span><span class="p" id="mwAb8">.</span><span class="nx" id="mwAcA">lastName</span><span class="si" id="mwAcE">}</span><span class="sb" id="mwAcI">`</span><span class="p" id="mwAcM">;</span> <span class="w" id="mwAcQ"> </span><span class="p" id="mwAcU">}</span> <span class="p" id="mwAcY">}</span> <span class="nx" id="mwAcc">Employee</span><span class="w" id="mwAcg"> </span><span class="nx" id="mwAck">zig</span><span class="w" id="mwAco"> </span><span class="o" id="mwAcs">=</span><span class="w" id="mwAcw"> </span><span class="ow" id="mwAc0">new</span><span class="w" id="mwAc4"> </span><span class="nx" id="mwAc8">Employee</span><span class="p" id="mwAdA">(</span><span class="s2" id="mwAdE">"Zig"</span><span class="p" id="mwAdI">,</span><span class="w" id="mwAdM"> </span><span class="s2" id="mwAdQ">"Ziglar"</span><span class="p" id="mwAdU">);</span> <span class="nx" id="mwAdY">Employee</span><span class="w" id="mwAdc"> </span><span class="nx" id="mwAdg">john</span><span class="w" id="mwAdk"> </span><span class="o" id="mwAdo">=</span><span class="w" id="mwAds"> </span><span class="ow" id="mwAdw">new</span><span class="w" id="mwAd0"> </span><span class="nx" id="mwAd4">Employee</span><span class="p" id="mwAd8">(</span><span class="s2" id="mwAeA">"John"</span><span class="p" id="mwAeE">,</span><span class="w" id="mwAeI"> </span><span class="s2" id="mwAeM">"Smith"</span><span class="p" id="mwAeQ">);</span> <span class="nx" id="mwAeU">Employee</span><span class="w" id="mwAeY"> </span><span class="nx" id="mwAec">abe</span><span class="w" id="mwAeg"> </span><span class="o" id="mwAek">=</span><span class="w" id="mwAeo"> </span><span class="ow" id="mwAes">new</span><span class="w" id="mwAew"> </span><span class="nx" id="mwAe0">Employee</span><span class="p" id="mwAe4">(</span><span class="s2" id="mwAe8">"Abe"</span><span class="p" id="mwAfA">,</span><span class="w" id="mwAfE"> </span><span class="s2" id="mwAfI">"Lincoln"</span><span class="p" id="mwAfM">);</span> <span class="nx" id="mwAfQ">Employee</span><span class="p" id="mwAfU">[]</span><span class="w" id="mwAfY"> </span><span class="nx" id="mwAfc">employees</span><span class="w" id="mwAfg"> </span><span class="o" id="mwAfk">=</span><span class="w" id="mwAfo"> </span><span class="p" id="mwAfs">[</span><span class="nx" id="mwAfw">zig</span><span class="p" id="mwAf0">,</span><span class="w" id="mwAf4"> </span><span class="nx" id="mwAf8">john</span><span class="p" id="mwAgA">,</span><span class="w" id="mwAgE"> </span><span class="nx" id="mwAgI">abe</span><span class="p" id="mwAgM">];</span> <span class="nx" id="mwAgQ">employees</span><span class="p" id="mwAgU">.</span><span class="nx" id="mwAgY">sort</span><span class="p" id="mwAgc">();</span> <span class="hll" id="mwAgg"><span class="nx" id="mwAgk">Console</span><span class="p" id="mwAgo">.</span><span class="nx" id="mwAgs">log</span><span class="p" id="mwAgw">(</span><span class="nx" id="mwAg0">employees</span><span class="p" id="mwAg4">.</span><span class="nx" id="mwAg8">join</span><span class="p" id="mwAhA">(</span><span class="s2" id="mwAhE">", "</span><span class="p" id="mwAhI">));</span> </span><span id="mwAhU"></span><span class="go" id="mwAhY">Abe Lincoln, John Smith, Zig Ziglar</span>
Thus, in the code above, the custom sorting logic provided is:
<span id="mwAho"></span><span class="k" id="mwAhs">return</span><span class="w" id="mwAhw"> </span><span class="k" id="mwAh0">this</span><span class="p" id="mwAh4">.</span><span class="nx" id="mwAh8">lastName</span><span class="p" id="mwAiA">.</span><span class="nx" id="mwAiE">compare</span><span class="p" id="mwAiI">(</span><span class="nx" id="mwAiM">that</span><span class="p" id="mwAiQ">.</span><span class="nx" id="mwAiU">lastName</span><span class="p" id="mwAiY">);</span>
Likewise, to call the sort:
<span id="mwAio"></span><span class="nx" id="mwAis">employees</span><span class="p" id="mwAiw">.</span><span class="nx" id="mwAi0">sort</span><span class="p" id="mwAi4">();</span>
For printing the sorted results:
<span id="mwAjI"></span><span class="nx" id="mwAjM">Console</span><span class="p" id="mwAjQ">.</span><span class="nx" id="mwAjU">log</span><span class="p" id="mwAjY">(</span><span class="nx" id="mwAjc">employees</span><span class="p" id="mwAjg">.</span><span class="nx" id="mwAjk">join</span><span class="p" id="mwAjo">(</span><span class="s2" id="mwAjs">", "</span><span class="p" id="mwAjw">));</span>
Example: encapsulation by default
JS++ provides encapsulation by default. In the following example, the fields x and y are private by default, even if no access modifier is specified. The methods getX() and getY() are public by default. This enables a more concise class definition syntax, as illustrated in the Point class below:
<span id="mwAk8"></span><span class="kd" id="mwAlA">class</span> <span class="nc" id="mwAlE">Point</span><span class="w" id="mwAlI"> </span><span class="p" id="mwAlM">{</span> <span class="w" id="mwAlQ"> </span><span class="kt" id="mwAlU">int</span><span class="w" id="mwAlY"> </span><span class="n" id="mwAlc">x</span><span class="p" id="mwAlg">;</span> <span class="w" id="mwAlk"> </span><span class="kt" id="mwAlo">int</span><span class="w" id="mwAls"> </span><span class="n" id="mwAlw">y</span><span class="p" id="mwAl0">;</span> <span class="w" id="mwAl4"> </span> <span class="w" id="mwAl8"> </span><span class="n" id="mwAmA">Point</span><span class="p" id="mwAmE">(</span><span class="kt" id="mwAmI">int</span><span class="w" id="mwAmM"> </span><span class="n" id="mwAmQ">x</span><span class="p" id="mwAmU">,</span><span class="w" id="mwAmY"> </span><span class="kt" id="mwAmc">int</span><span class="w" id="mwAmg"> </span><span class="n" id="mwAmk">y</span><span class="p" id="mwAmo">)</span><span class="w" id="mwAms"> </span><span class="p" id="mwAmw">{</span> <span class="w" id="mwAm0"> </span><span class="k" id="mwAm4">this</span><span class="p" id="mwAm8">.</span><span class="na" id="mwAnA">x</span><span class="w" id="mwAnE"> </span><span class="o" id="mwAnI">=</span><span class="w" id="mwAnM"> </span><span class="n" id="mwAnQ">x</span><span class="p" id="mwAnU">;</span> <span class="w" id="mwAnY"> </span><span class="k" id="mwAnc">this</span><span class="p" id="mwAng">.</span><span class="na" id="mwAnk">y</span><span class="w" id="mwAno"> </span><span class="o" id="mwAns">=</span><span class="w" id="mwAnw"> </span><span class="n" id="mwAn0">y</span><span class="p" id="mwAn4">;</span> <span class="w" id="mwAn8"> </span><span class="p" id="mwAoA">}</span> <span class="w" id="mwAoE"> </span> <span class="w" id="mwAoI"> </span><span class="kt" id="mwAoM">int</span><span class="w" id="mwAoQ"> </span><span class="nf" id="mwAoU">getX</span><span class="p" id="mwAoY">()</span><span class="w" id="mwAoc"> </span><span class="p" id="mwAog">{</span> <span class="w" id="mwAok"> </span><span class="k" id="mwAoo">return</span><span class="w" id="mwAos"> </span><span class="k" id="mwAow">this</span><span class="p" id="mwAo0">.</span><span class="na" id="mwAo4">x</span><span class="p" id="mwAo8">;</span><span class="w" id="mwApA"> </span> <span class="w" id="mwApE"> </span><span class="p" id="mwApI">}</span> <span class="w" id="mwApM"> </span><span class="kt" id="mwApQ">int</span><span class="w" id="mwApU"> </span><span class="nf" id="mwApY">getY</span><span class="p" id="mwApc">()</span><span class="w" id="mwApg"> </span><span class="p" id="mwApk">{</span><span class="w" id="mwApo"> </span> <span class="w" id="mwAps"> </span><span class="k" id="mwApw">return</span><span class="w" id="mwAp0"> </span><span class="k" id="mwAp4">this</span><span class="p" id="mwAp8">.</span><span class="na" id="mwAqA">y</span><span class="p" id="mwAqE">;</span><span class="w" id="mwAqI"> </span> <span class="w" id="mwAqM"> </span><span class="p" id="mwAqQ">}</span> <span class="p" id="mwAqU">}</span>Out-of-bounds analysis
An out-of-bounds access usually occurs with arrays and other containers. For example, when we access the 100th element of a 3-element array, we have an out-of-bounds access:
<span id="mwAqs"></span><span class="kr" id="mwAqw">int</span><span class="p" id="mwAq0">[]</span><span class="w" id="mwAq4"> </span><span class="nx" id="mwAq8">arr</span><span class="w" id="mwArA"> </span><span class="o" id="mwArE">=</span><span class="w" id="mwArI"> </span><span class="p" id="mwArM">[</span><span class="mf" id="mwArQ">1</span><span class="p" id="mwArU">,</span><span class="w" id="mwArY"> </span><span class="mf" id="mwArc">2</span><span class="p" id="mwArg">,</span><span class="w" id="mwArk"> </span><span class="mf" id="mwAro">3</span><span class="p" id="mwArs">];</span> <span class="nx" id="mwArw">Console</span><span class="p" id="mwAr0">.</span><span class="nx" id="mwAr4">log</span><span class="p" id="mwAr8">(</span><span class="nx" id="mwAsA">arr</span><span class="p" id="mwAsE">[</span><span class="mf" id="mwAsI">100</span><span class="p" id="mwAsM">]);</span><span class="w" id="mwAsQ"> </span><span class="c1" id="mwAsU">// out-of-bounds access, 'arr' does not have an element at index 100</span>
In Java and C#, this can result in an exception and program termination. In C, this can result in buffer overflows or segmentation faults. C++ has varying semantics, such as default initialization, exceptions, segmentation faults, or buffer overflows.
JS++ can efficiently analyze and prevent out-of-bounds errors at compile time.
JavaScript has the notion of null and undefined values, where null means a value is present but it is an empty value, and undefined means there isn't a value there at all. JS++ extends this intuition further to differentiate between empty values and out-of-bounds accesses.
Consider the following code, with a nullable int type represented with int?:
<span id="mwAvg"></span><span class="kr" id="mwAvk">int</span><span class="p" id="mwAvo">[]</span><span class="w" id="mwAvs"> </span><span class="nx" id="mwAvw">a</span><span class="w" id="mwAv0"> </span><span class="o" id="mwAv4">=</span><span class="w" id="mwAv8"> </span><span class="p" id="mwAwA">[</span><span class="mf" id="mwAwE">1</span><span class="p" id="mwAwI">,</span><span class="w" id="mwAwM"> </span><span class="mf" id="mwAwQ">2</span><span class="p" id="mwAwU">];</span> <span class="kr" id="mwAwY">int</span><span class="o" id="mwAwc">?</span><span class="w" id="mwAwg"> </span><span class="nx" id="mwAwk">value1</span><span class="w" id="mwAwo"> </span><span class="o" id="mwAws">=</span><span class="w" id="mwAww"> </span><span class="nx" id="mwAw0">a</span><span class="p" id="mwAw4">[</span><span class="mf" id="mwAw8">2</span><span class="p" id="mwAxA">];</span> <span class="k" id="mwAxE">if</span><span class="w" id="mwAxI"> </span><span class="p" id="mwAxM">(</span><span class="nx" id="mwAxQ">value1</span><span class="w" id="mwAxU"> </span><span class="o" id="mwAxY">==</span><span class="w" id="mwAxc"> </span><span class="kc" id="mwAxg">null</span><span class="p" id="mwAxk">)</span><span class="w" id="mwAxo"> </span><span class="p" id="mwAxs">{</span> <span class="w" id="mwAxw"> </span><span class="nx" id="mwAx0">Console</span><span class="p" id="mwAx4">.</span><span class="nx" id="mwAx8">log</span><span class="p" id="mwAyA">(</span><span class="s2" id="mwAyE">"Definitely out of bounds"</span><span class="p" id="mwAyI">);</span> <span class="p" id="mwAyM">}</span> <span class="w" id="mwAyQ"> </span> <span class="kr" id="mwAyU">int</span><span class="o" id="mwAyY">?</span><span class="p" id="mwAyc">[]</span><span class="w" id="mwAyg"> </span><span class="nx" id="mwAyk">b</span><span class="w" id="mwAyo"> </span><span class="o" id="mwAys">=</span><span class="w" id="mwAyw"> </span><span class="p" id="mwAy0">[</span><span class="mf" id="mwAy4">1</span><span class="p" id="mwAy8">,</span><span class="w" id="mwAzA"> </span><span class="kc" id="mwAzE">null</span><span class="p" id="mwAzI">];</span> <span class="kr" id="mwAzM">int</span><span class="o" id="mwAzQ">?</span><span class="w" id="mwAzU"> </span><span class="nx" id="mwAzY">value2</span><span class="w" id="mwAzc"> </span><span class="o" id="mwAzg">=</span><span class="w" id="mwAzk"> </span><span class="nx" id="mwAzo">b</span><span class="p" id="mwAzs">[</span><span class="mf" id="mwAzw">2</span><span class="p" id="mwAz0">];</span> <span class="k" id="mwAz4">if</span><span class="w" id="mwAz8"> </span><span class="p" id="mwA0A">(</span><span class="nx" id="mwA0E">value2</span><span class="w" id="mwA0I"> </span><span class="o" id="mwA0M">==</span><span class="w" id="mwA0Q"> </span><span class="kc" id="mwA0U">null</span><span class="p" id="mwA0Y">)</span><span class="w" id="mwA0c"> </span><span class="p" id="mwA0g">{</span> <span class="w" id="mwA0k"> </span><span class="nx" id="mwA0o">Console</span><span class="p" id="mwA0s">.</span><span class="nx" id="mwA0w">log</span><span class="p" id="mwA00">(</span><span class="s2" id="mwA04">"Might be out of bounds, might just be an access of a null element"</span><span class="p" id="mwA08">);</span> <span class="p" id="mwA1A">}</span>While nullable types can represent an out-of-bounds access, it falls apart when the array might contain nullable values as illustrated above. Instead, JS++ introduces an additional concept in addition to null values: undefined values. Recall that JS++ extends the JavaScript notion that null means a value is present but is an empty value, while an undefined value means a value does not exist at all. JS++ uses the concept of "a value does not exist at all" to mean an out-of-bounds access has occurred, and this concept is known in JS++ as "existent types."
Therefore, the previous example can be amended. The existent type int+ means "int or out of bounds" and int?+ means "int, null, or out of bounds":
<span id="mwA2c"></span><span class="kr" id="mwA2g">int</span><span class="p" id="mwA2k">[]</span><span class="w" id="mwA2o"> </span><span class="nx" id="mwA2s">a</span><span class="w" id="mwA2w"> </span><span class="o" id="mwA20">=</span><span class="w" id="mwA24"> </span><span class="p" id="mwA28">[</span><span class="mf" id="mwA3A">1</span><span class="p" id="mwA3E">,</span><span class="w" id="mwA3I"> </span><span class="mf" id="mwA3M">2</span><span class="p" id="mwA3Q">];</span> <span class="kr" id="mwA3U">int</span><span class="o" id="mwA3Y">?</span><span class="w" id="mwA3c"> </span><span class="nx" id="mwA3g">value1</span><span class="w" id="mwA3k"> </span><span class="o" id="mwA3o">=</span><span class="w" id="mwA3s"> </span><span class="nx" id="mwA3w">a</span><span class="p" id="mwA30">[</span><span class="mf" id="mwA34">2</span><span class="p" id="mwA38">];</span> <span class="k" id="mwA4A">if</span><span class="w" id="mwA4E"> </span><span class="p" id="mwA4I">(</span><span class="nx" id="mwA4M">value1</span><span class="w" id="mwA4Q"> </span><span class="o" id="mwA4U">==</span><span class="w" id="mwA4Y"> </span><span class="kc" id="mwA4c">undefined</span><span class="p" id="mwA4g">)</span><span class="w" id="mwA4k"> </span><span class="p" id="mwA4o">{</span> <span class="w" id="mwA4s"> </span><span class="nx" id="mwA4w">Console</span><span class="p" id="mwA40">.</span><span class="nx" id="mwA44">log</span><span class="p" id="mwA48">(</span><span class="s2" id="mwA5A">"Definitely out of bounds"</span><span class="p" id="mwA5E">);</span> <span class="p" id="mwA5I">}</span> <span class="kr" id="mwA5M">int</span><span class="o" id="mwA5Q">?</span><span class="p" id="mwA5U">[]</span><span class="w" id="mwA5Y"> </span><span class="nx" id="mwA5c">b</span><span class="w" id="mwA5g"> </span><span class="o" id="mwA5k">=</span><span class="w" id="mwA5o"> </span><span class="p" id="mwA5s">[</span><span class="mf" id="mwA5w">1</span><span class="p" id="mwA50">,</span><span class="w" id="mwA54"> </span><span class="kc" id="mwA58">null</span><span class="p" id="mwA6A">];</span> <span class="kr" id="mwA6E">int</span><span class="o" id="mwA6I">?+</span><span class="w" id="mwA6M"> </span><span class="nx" id="mwA6Q">value2</span><span class="w" id="mwA6U"> </span><span class="o" id="mwA6Y">=</span><span class="w" id="mwA6c"> </span><span class="nx" id="mwA6g">b</span><span class="p" id="mwA6k">[</span><span class="mf" id="mwA6o">2</span><span class="p" id="mwA6s">];</span> <span class="k" id="mwA6w">if</span><span class="w" id="mwA60"> </span><span class="p" id="mwA64">(</span><span class="nx" id="mwA68">value2</span><span class="w" id="mwA7A"> </span><span class="o" id="mwA7E">==</span><span class="w" id="mwA7I"> </span><span class="kc" id="mwA7M">undefined</span><span class="p" id="mwA7Q">)</span><span class="w" id="mwA7U"> </span><span class="p" id="mwA7Y">{</span> <span class="w" id="mwA7c"> </span><span class="nx" id="mwA7g">Console</span><span class="p" id="mwA7k">.</span><span class="nx" id="mwA7o">log</span><span class="p" id="mwA7s">(</span><span class="s2" id="mwA7w">"Definitely out of bounds"</span><span class="p" id="mwA70">);</span> <span class="p" id="mwA74">}</span>Intuitively, this means existent types cannot be used as the underlying type for array elements. JS++ enforces this at compile time:
<span id="mwA8I"></span><span class="kt" id="mwA8M">int</span><span class="o" id="mwA8Q">+</span><span class="p" id="mwA8U">[]</span><span class="w" id="mwA8Y"> </span><span class="n" id="mwA8c">arr</span><span class="w" id="mwA8g"> </span><span class="o" id="mwA8k">=</span><span class="w" id="mwA8o"> </span><span class="p" id="mwA8s">[];</span><span class="w" id="mwA8w"> </span><span class="c1" id="mwA80">// ERROR</span>
<span id="mwA9A"></span><span class="go" id="mwA9E">[ ERROR ] JSPPE5204: Existent type `int+' cannot be used as the element type for arrays</span>
Instead of following every conditional branch or virtual method call path, which would result in path explosion and exponential compile times, existent types have essentially the same compile-time analysis cost as int, bool, and other primitive types. Consequently, compile times have been shown to be unaffected (±1-2ms) by the introduction of existent types. Since existent types are used for all array and container types in JS++ (such as hash maps, System.Stack<T>, and System.Queue<T>), JS++ containers are thus guaranteed to not have out-of-bounds errors.
In JS++, undefined is a value that cannot be changed. In JavaScript (ECMAScript 3), undefined is a mutable property of the global object, resulting in circumstances where "undefined" can be "defined." Thus, existent types would not have been possible in pure JavaScript, as arrays can contain elements with the undefined value, undefined can be defined, or other edge and corner cases that are prevented in JS++.
Also, in comparison to Java and early object-oriented languages such as Eiffel, JS++ does not default initialize objects to null. Instead, the compiler enforces initialization by the programmer:
<span id="mwBAU"></span><span class="kd" id="mwBAY">class</span><span class="w" id="mwBAc"> </span><span class="nx" id="mwBAg">Car</span><span class="w" id="mwBAk"> </span><span class="p" id="mwBAo">{}</span> <span class="nx" id="mwBAs">Car</span><span class="w" id="mwBAw"> </span><span class="nx" id="mwBA0">car</span><span class="p" id="mwBA4">;</span><span id="mwBBE"></span><span class="go" id="mwBBI">[ ERROR ] JSPPE6000: Variable `car' is not initialized at line 3 char 4</span>
Therefore, since existent types are deeply embedded into the language, JS++ can guarantee that out-of-bounds errors never occur.
Databases
The concept of existent types can be extended outside of containers. For example, in MySQL, columns can be nullable. If the row does not exist for a specified condition (e.g. WHERE clause), the undefined value can be returned. However, if the row does exist but the value at the column is empty, a null value can be returned instead. This can simplify the code and interfaces to the data access layer.
Integer types
JS++ provides 8-bit, 16-bit, 32-bit, and 64-bit integer types as well as floating point types:
<span id="mwBDE"></span><span class="kt" id="mwBDI">byte</span><span class="w" id="mwBDM"> </span><span class="n" id="mwBDQ">b1</span><span class="w" id="mwBDU"> </span><span class="o" id="mwBDY">=</span><span class="w" id="mwBDc"> </span><span class="mh" id="mwBDg">0xFF</span><span class="p" id="mwBDk">;</span><span class="w" id="mwBDo"> </span><span class="c1" id="mwBDs">// unsigned 8-bit</span> <span class="kt" id="mwBDw">signed</span><span class="w" id="mwBD0"> </span><span class="kt" id="mwBD4">byte</span><span class="w" id="mwBD8"> </span><span class="n" id="mwBEA">b2</span><span class="w" id="mwBEE"> </span><span class="o" id="mwBEI">=</span><span class="w" id="mwBEM"> </span><span class="mi" id="mwBEQ">-1</span><span class="p" id="mwBEU">;</span><span class="w" id="mwBEY"> </span><span class="c1" id="mwBEc">// signed 8-bit</span> <span class="kt" id="mwBEg">short</span><span class="w" id="mwBEk"> </span><span class="n" id="mwBEo">s1</span><span class="w" id="mwBEs"> </span><span class="o" id="mwBEw">=</span><span class="w" id="mwBE0"> </span><span class="mi" id="mwBE4">1</span><span class="p" id="mwBE8">;</span><span class="w" id="mwBFA"> </span><span class="c1" id="mwBFE">// signed 16-bit</span> <span class="kt" id="mwBFI">unsigned</span><span class="w" id="mwBFM"> </span><span class="kt" id="mwBFQ">short</span><span class="w" id="mwBFU"> </span><span class="n" id="mwBFY">s2</span><span class="w" id="mwBFc"> </span><span class="o" id="mwBFg">=</span><span class="w" id="mwBFk"> </span><span class="mi" id="mwBFo">1</span><span class="p" id="mwBFs">;</span><span class="w" id="mwBFw"> </span><span class="c1" id="mwBF0">// unsigned 16-bit</span> <span class="kt" id="mwBF4">int</span><span class="w" id="mwBF8"> </span><span class="n" id="mwBGA">x1</span><span class="w" id="mwBGE"> </span><span class="o" id="mwBGI">=</span><span class="w" id="mwBGM"> </span><span class="mi" id="mwBGQ">0</span><span class="p" id="mwBGU">;</span><span class="w" id="mwBGY"> </span><span class="c1" id="mwBGc">// signed 32-bit</span> <span class="kt" id="mwBGg">unsigned</span><span class="w" id="mwBGk"> </span><span class="kt" id="mwBGo">int</span><span class="w" id="mwBGs"> </span><span class="n" id="mwBGw">x2</span><span class="w" id="mwBG0"> </span><span class="o" id="mwBG4">=</span><span class="w" id="mwBG8"> </span><span class="mi" id="mwBHA">0</span><span class="p" id="mwBHE">;</span><span class="w" id="mwBHI"> </span><span class="c1" id="mwBHM">// unsigned 32-bit</span> <span class="kt" id="mwBHQ">long</span><span class="w" id="mwBHU"> </span><span class="n" id="mwBHY">z1</span><span class="w" id="mwBHc"> </span><span class="o" id="mwBHg">=</span><span class="w" id="mwBHk"> </span><span class="mi" id="mwBHo">1</span><span class="p" id="mwBHs">;</span><span class="w" id="mwBHw"> </span><span class="c1" id="mwBH0">// signed 64-bit</span> <span class="kt" id="mwBH4">unsigned</span><span class="w" id="mwBH8"> </span><span class="kt" id="mwBIA">long</span><span class="w" id="mwBIE"> </span><span class="n" id="mwBII">z2</span><span class="w" id="mwBIM"> </span><span class="o" id="mwBIQ">=</span><span class="w" id="mwBIU"> </span><span class="mi" id="mwBIY">1</span><span class="p" id="mwBIc">;</span><span class="w" id="mwBIg"> </span><span class="c1" id="mwBIk">// unsigned 64-bit</span> <span class="kt" id="mwBIo">float</span><span class="w" id="mwBIs"> </span><span class="n" id="mwBIw">f</span><span class="w" id="mwBI0"> </span><span class="o" id="mwBI4">=</span><span class="w" id="mwBI8"> </span><span class="mf" id="mwBJA">0.5</span><span class="p" id="mwBJE">;</span><span class="w" id="mwBJI"> </span><span class="c1" id="mwBJM">// single-precision floating point</span> <span class="kt" id="mwBJQ">double</span><span class="w" id="mwBJU"> </span><span class="n" id="mwBJY">d</span><span class="w" id="mwBJc"> </span><span class="o" id="mwBJg">=</span><span class="w" id="mwBJk"> </span><span class="mf" id="mwBJo">0.5</span><span class="p" id="mwBJs">;</span><span class="w" id="mwBJw"> </span><span class="c1" id="mwBJ0">// double-precision floating point</span>
From the project homepage:
<span id="mwBKE"></span><span class="c1" id="mwBKI">// You're not required to declare the type for a variable and you can just</span> <span class="c1" id="mwBKM">// keep writing regular JavaScript (again, NO learning curve):</span> <span class="n" id="mwBKQ">var</span><span class="w" id="mwBKU"> </span><span class="n" id="mwBKY">offset</span><span class="w" id="mwBKc"> </span><span class="o" id="mwBKg">=</span><span class="w" id="mwBKk"> </span><span class="mi" id="mwBKo">0</span><span class="p" id="mwBKs">;</span> <span class="c1" id="mwBKw">// But, if you do, this next variable will always remain an 'unsigned int' - even at runtime.</span> <span class="c1" id="mwBK0">// You'll never see NaN ("Not a Number") runtime errors again.</span> <span class="c1" id="mwBK4">// This variable is 'unsigned' so it's also guaranteed to never be negative.</span> <span class="kt" id="mwBK8">unsigned</span><span class="w" id="mwBLA"> </span><span class="kt" id="mwBLE">int</span><span class="w" id="mwBLI"> </span><span class="n" id="mwBLM">pageHeight</span><span class="w" id="mwBLQ"> </span><span class="o" id="mwBLU">=</span><span class="w" id="mwBLY"> </span><span class="n" id="mwBLc">$</span><span class="p" id="mwBLg">(</span><span class="n" id="mwBLk">document</span><span class="p" id="mwBLo">).</span><span class="n" id="mwBLs">height</span><span class="p" id="mwBLw">();</span>Block scoping
All variables in JS++ are block-scoped, including the JavaScript var statement. Thus, there is no need for two different variable declaration keywords with different scoping rules, such as var and let co-existing simultaneously in JavaScript (ECMAScript 6).
Development tools
Compiler
The JS++ compiler is available for Windows, macOS, and Linux. It is a source-to-source compiler which emits JavaScript source code as an intermediate representation.
The compiler is developed with C/C++, and the developers claim there are "fewer than 10 open bug reports in the core compiler" after 3.5 years of engineering and 400,000 lines of code.
Editor integration
JS++ integrates with various code editors including Visual Studio Code, Atom, and Sublime Text.
Build tools
JS++ can be integrated with third-party build tools like Webpack.

