JS++ 0.8.5: Bug Fix Release

This is a small bug fix release.

The following minor issues have been fixed:

  1. Dictionary expression of empty arrays now has the correct type inferred
  2. Labels for foreach statements
  3. Type inference for System.Array.reduce
  4. Function inlining for System.String methods: padRight(int), padLeft(int), startsWith, endsWith

Issue #1:

Dictionary<unsigned int[]> x = {
    "foo": (unsigned int[]) [],
    "bar": (unsigned int[]) []

The casts were previously required in 0.8.4, but, in the latest release, casting of empty arrays is no longer necessary.

Issue #2:

outerLoop: foreach (var row in json) {
    // ...

    foreach(var cell in row.Cell) {
        // ...
        continue outerLoop;

Issue #3:

string[] keys = dict.keys();
int x = keys.reduce(
    int(string previous /* type of 'previous' param */, string current) {
    0 // and this type

In the above case, the two types must match. However, the type checker was inferring ‘external’ instead. This has been fixed in the latest release.

JS++ 0.8.4: Advanced Generics and System.String Expansion

We have significantly expanded the Standard Library with this release. In particular, System.String has undergone significant expansion.

System.String Highlights


string quotedWords = '"duck" "swan" "crab"';
// 'between' is smart enough to allow the same string to be used as a start and end delimiter
string[] words = quotedWords.between('"', '"');
Console.log(words); // [ "duck", "swan", "crab" ]

Documentation page: click here

format: C-like printf

"%s is %d years old".format("Joe", 10) // Joe is 10 years old

Documentation page: click here


"a\r\nb".escape() // a\\r\\nb

Documentation page: click here


string text = "The quick brown fox jumped over the lazy dog.";
Console.log(text.truncate(9)); // "The quick..."

Documentation page: click here


"*".repeat(5) // *****

Documentation page: click here


"foobar".count("foo") // 1
"FOOBAR".icount("foo") // 1

Documentation (count): click here
Documentation (icount): click here


"abc".contains("b") // true
"ABC".icontains("b") // true

Documentation (contains): click here
Documentation (icontains): click here

New System.String Methods

Here are all the new methods available for strings in JS++:

  • between – Gets substrings between two delimiters (does not use regex)
  • compact – Removes whitespace globally
  • contains/icontains
  • count/icount
  • countLines
  • countNonEmptyLines
  • startsWith/endsWith
  • escape/unescape – Escape the escape sequence characters (e.g. \n -> \\n)
  • escapeQuotes/unescapeQuotes
  • format – Similar to C’s printf
  • insert/append/prepend
  • isEmpty – uses .length === 0 rather than str1 === “” for performance, not everyone has time to benchmark every detail
  • isLowerCase
  • isUpperCase
  • isWhitespace
  • joinLines – collapses a string composed of multiple lines into a single line
  • joinNonEmptyLines
  • padLeft/padRight – remember the NPM debacle?
  • quote/quoteSingle – wraps the string in quotes
  • unquote – removes quote pairs
  • repeat – “*”.repeat(3) == “***”
  • reverse
  • splitLines – splits a string into a string[] (array) based on newlines
  • trim, trimLeft, trimRight, trimMulti, trimMultiLeft, trimMultiRight
  • truncate – Cuts off the string at the specified length (with support for custom ellipsis)

There are close to 50 new string methods (48 including overloads, 39 otherwise), and these methods should cover most application-level usages. With documentation, this resulted in +1400 new lines of code to System.String. I’m happy to announce we actually still have more methods (for System.String and others) on the way.

Every single method is documented. All documentation is online and available at the System.String index page.

We avoided regular expressions as much as possible to avoid runtime FSM construction, which takes time and space. Therefore, prefer JS++ methods such as "abc".endsWith("c") over the traditional regex/JavaScript /c$/.test("abc").

The best thing about JS++ is that it’s a compiled language. This gives you performance benefits that a JavaScript library with string utilities can never give you. For example:

if ("abc".isEmpty());


if ("abc".length===0);





The astute observer will notice that both the above methods can be further optimized to reach “perfect” optimization. However, there is no optimizing compiler inside JS++ yet, and inserting branching logic into the code generator will result in technical debt.

Our goal with the Standard Library is to make it easier than ever to write applications compared to JavaScript. Side effects of our work on the JS++ Standard Library are performance, size, and correctness. JS++ dead code elimination means we can add hundreds of methods to System.String, but you only pay for the methods you actually use. For performance, not every team can afford to hire a JavaScript performance expert. Even if you have the performance expert, he can’t be expected to micro-optimize and benchmark every method.

Finally, with the JS++ Standard Library, we can fully avoid the NPM left-pad debacle.

import System;

Console.log("1".padLeft(4, "0")); // "0001"


Previously, to convert a string to number in JS++, it was a little unintuitive. For example:

int x = +"1000"; // use the unary + operator

For all numeric types, we’ve introduced the fromString, fromStringOr, and fromStringOrThrow static methods. The above example can be re-written to use Integer32.fromString:

int x = Integer32.fromString("1000");

Advanced Generics

JS++ 0.8.4 introduces covariant and contravariant generic types (including upcasting and downcasting for types with variants). Covariance and contravariance are based on use-site variance. At this time, we are not introducing declaration-site variance at all; we have higher priorities. In addition, we’ve introduced generic constraints (subtype constraints, multiple constraints, wildcard constraints, and more).

Finally, we have support for generic functions and generic static methods.

Everything from basic to advanced generic programming in JS++ is covered in our generic programming documentation.

When we released version 0.8.0, we introduced only basic generics. In today’s 0.8.4 release, you can consider generics fully implemented.

I highly encourage reading the generic programming documentation. To put it all together, here’s generic covariance and contravariance together with use-site variance:

import System;
abstract class Animal {}
class Tiger : Animal {}
abstract class Pet : Animal {}
class Dog : Pet {}
class Cat : Pet {}
class PetCollection
    Pet[] data = [];
    void insert(descend Pet[] pets) {
        foreach(Pet pet in pets) {
    ascend Pet[] get() {
        return this.data;
auto myPets = new PetCollection();
// Write operations (descend, covariance)
myPets.insert([ new Dog, new Cat ]);
// myPets.insert([ new Tiger ]); // not allowed
// Read operations (ascend, contravariance)
Pet[] getPets = [];
Animal[] getAnimals = [];
ascend Pet[] tmp = myPets.get(); // read here
foreach(Pet pet in tmp) { // but we still need to put them back into our "result" arrays
// Now we can modify the arrays we read into above
getPets.push(new Dog);
getAnimals.push(new Dog);
getAnimals.push(new Tiger);
// getPets.push(new Tiger); // ERROR

Other Changes

  • Fix return types for System.String.charAt and System.String.charCodeAt
  • Fix type promotion to ‘double’. We now handle this better than languages like Java and C#. Thanks to our lead engineer, Anton, for the idea.
  • isEven() and isOdd(). You might think this is fizz buzz, but if you’re using the modulus operator, it’ll be slower. We use bitwise operations, and you might be interested in reading this article on how we took advantage of overflow behavior to improve performance while preserving correctness.
  • Fix System.Array.map and System.Array.reduce to support wildcard generic types.
  • Type inference of generic parameters for function calls. This is needed for System.Array.map and System.Array.reduce, but it’s also available for user-side code.
  • Fix System.Console.error when no console is available
  • Fixed error message with incorrect type for setters defined with no accompanying getters.
  • Fixed private access modifier for modules in a multi-file setting.
  • Fix callback types as generic arguments
  • Fix enum bitwise operations to reduce explicit casting

Leveraging Integer Overflow to Improve Performance While Preserving Correctness

If you use the upcoming UInteger32.isEven or isOdd methods, you’ll notice that it uses a bitwise AND operation. The reason, as described in a previous post, is because it improves performance.

However, while this is straightforward for all other integer wrapper classes, UInteger32 is an exception. According to ECMAScript 3 11.10:

The production A : A @B, where @ is one of the bitwise operators in the productions above, is evaluated as follows:

  1. Evaluate A.
  2. Call GetValue(Result(1)).
  3. Evaluate B.
  4. Call GetValue(Result(3)).
  5. Call ToInt32(Result(2)).
  6. Call ToInt32(Result(4)).
  7. Apply the bitwise operator @ to Result(5) and Result(6). The result is a signed 32 bit integer.
  8. Return Result(7).

The operands (and, thus, the result type) for the bitwise AND operation in ECMAScript are converted to 32-bit signed integers. System.UInteger32 represents an unsigned 32-bit integer.

This is inconvenient because we’d obviously have to fall back to the slower modulus operation for isEven/isOdd on UInteger32. Unless…

((Math.pow(2, 32) + 1) >>> 0 | 0) & 1 // true
((Math.pow(2, 32) + 2) >>> 0 | 0) & 1 // false

We can take advantage of overflow behavior. (Note: Since we’re able to get the correct result by leveraging overflow behavior, we actually don’t perform the extraneous zero-fill right shift as illustrated in the example.)

This is completely safe because:

A) Mathematically, in base 2, the last bit will always be 1 for odd numbers and 0 for even numbers… no matter how big the number is.

B) Bitwise AND will compare both bits in equal-length binary forms. Thus, no matter how big the number is, when you AND against 1, it will always be 0000001 (or zero-padded to whatever length is needed). Therefore, all the preceding bits don’t matter because they will always be ANDed against a zero bit. The only bit that matters is the trailing bit; see A for why this will always work.

Standard Library Performance: isEven() and isOdd()

Remember what I always advise: always use the JS++ Standard Library if you can. The methods aren’t just well-tested for validity, but we also test for performance.

Checking if a number is even or odd is the classic fizzbuzz test. Most professional developers can use the modulus operator. However, that’s not always the fastest implementation.

> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i & 1) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i & 1) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i & 1) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i & 1) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i & 1) == 0; console.log(x); new Date - t;

= 87ms

> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i % 2) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i % 2) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i % 2) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i % 2) == 0; console.log(x); new Date - t;
> var t = new Date(); var x; for (var i = 0; i < 50000000; ++i) x = (i % 2) == 0; console.log(x); new Date - t;

= 102ms

Node.js v8.11.1 Linux x64
Core i7-4790k, 32gb RAM
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i & 1) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
1948 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i & 1) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2072 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i & 1) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2086 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i & 1) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2092 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i & 1) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80

= 2060ms

var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i % 2) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2058 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i % 2) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2082 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i % 2) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2114 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i % 2) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2102 debugger eval code:1:96
var t = new Date(); var x; for (var i = 0; i < 5000000; ++i) x = (i % 2) == 0; console.log(x); console.log(new Date - t);
false debugger eval code:1:80
2104 debugger eval code:1:96

= 2092ms

Firefox 59.0.2, Linux x64
Core i7-4790k, 32gb RAM

While the results are not statistically significant in Firefox (because it's very possible SpiderMonkey is manually optimizing this case via a pattern-matched optimization), you can get a 17% performance gain in Node.js via bitwise AND.

Due to all the layers of abstraction in JavaScript, it's not entirely evident how much faster a bitwise AND for isEven/isOdd can really be. In our benchmarks, we were able to achieve a 17% performance improvement in Node.js. As our lead engineer pointed out via email, according to this table, "for Intel Skylake-X `div` has a latency of 26 (for 32-bit integers), whereas `and` has latency 1 ("reciprocal throughput" has similar difference) so it is an order of magnitude slower, not 20% as in your tests."

Look for isEven() and isOdd() to appear in a future version of the JS++ Standard Library.

You may also be interested in reading Part II of this post which describes how we leveraged overflow behavior to improve performance while preserving correctness for UInteger32.

Google Image Search Broken with TypeErrors

First of all, this is not an April Fools joke. It’s unfortunate that Easter Sunday falls on April Fools Day.

Google Image Search isn’t working with custom image sizes on Easter Sunday. A closer inspection reveals a plethora of runtime TypeErrors:

When you click “Go” above, nothing happens. Form submissions that do nothing are a common problem with JavaScript runtime failures.

It’s important to remember, with JS++ “type guarantees,” it is possible to completely eliminate type errors via a sound type system.


This bug is still happening as of Monday, April 2. It’s happening as far as Russia. Steps to reproduce:

1. Go to google.com
2. Search “black forest”
3. Navigate to Image Search
4. Under Tools -> Size -> Exactly… Try 1920×1080.

JS++ 0.8.1: auto, catch-all, and Time

JS++ 0.8.1 fixes two major bug fixes that appeared when we introduced generics (0.8.0) and introduces some very useful new features. If you come from a C++ background, you might appreciate some of the new syntax :-).

‘auto’ Keyword

With the introduction of generic programming in 0.8.0, we need a more concise syntax to instantiate generic classes. The auto keyword solves this problem.

Now, instead of the following:

VeryLongClassName<string> foo = new VeryLongClassName<string>();

You can instead instantiate classes using auto:

auto foo = new VeryLongClassName<string>();

auto can be used for more than just generic classes though:

class Foo {}

auto foo = new Foo();

The auto keyword can only be used for variable declarations, and it reduces the redundancy of having to specify the type on the left-hand side only to repeat yourself on the right-hand side. This is known as local-variable type inference (to use the Java 10 terminology). For fans of C++, you may recognize this syntax.

Catch-all Clauses

This is another syntax that comes from C++.

Sometimes, you’ll want to catch an exception, but you don’t care to do anything with the exception object. In other cases, you may want to catch a specific type of exception but ignore all other exceptions. The “catch-all” clause can help you:

import System;

try {
    throw new System.Exception();
catch(System.Exception e) {
catch(...) {
    Console.log("The catch-all clause provides no exception object but will catch all exceptions - whether the type of the exception is internal or external.");
import Externals.JS;

try {
    throw new ReferenceError();
catch(...) {
    Console.log("Do nothing");


JS++ has an emphasis on readability. Have you ever seen code that looks like this?

setInterval(function() { /* ... */ }, 3600000);

The System.Time module has been introduced for dealing with time. Specifically, we’ve introduced a TimeUnits module to directly deal with the above case:

import System.Time;
external setInterval;

setInterval(void() { /* ... */ }, TimeUnits.hours(1));

Or, more succinctly:

import System.Time.TimeUnits;
external setInterval;

setInterval(void() { /* ... */ }, hours(1));

As always, we’ve had a focus on readable code. Here’s a preview of how well this composes:

import System;
import System.Time.TimeUnits;

Console.log(hours(1) + minutes(5));


In JavaScript, functions such as setTimeout and setInterval are not part of the ECMAScript standard; they are provided by the host environment. Web browsers and Node.js ship with these functions, but it would not have been correct to add this to the Externals.JS module. Therefore, we’ve introduced the Externals.Time external module so you can more clearly work with timers.

Bug Fixes

  • Fixed methods with variadic parameters passing by reference
  • Fixed implementing of generic interfaces from generic classes
  • MAJOR BUG FIX: Fixed double calls being generated for getters
  • MAJOR BUG FIX: Fix this binding in code generation

JS++ 0.8.0: Altitude MVC, Generics, System.Dictionary, and More

This is a major update that has been in the works for a while.

Altitude MVC

Altitude MVC

Altitude is an MVC/MVP framework for JS++. It follows a “pure MVC” approach. In other words, the user uses the controller to manipulate the model, the model updates the view, and the view is fed back to the user as explained in this diagram from Wikipedia.

The “pure MVC” approach has historically proven to scale. Internally, we have tested Altitude for an application consisting of 3,000+ lines of JS++ code, and it has served us well.

Lastly, Altitude contains fewer than 100 lines of code (if you remove comments and whitespace). In an age when load times influence search rankings and you can get downgraded to a 2G/3G connection at any time, it’s important for libraries to be as lightweight as possible. However, there is one external JavaScript dependency (Handlebars.js), and, optionally, jQuery.

Despite the small size of the library, we’ve managed to scale it for a relatively large and complex internal email application. Examples are included to get you started. As usual, we also spoil you with documentation.

Download it here.


The major new language feature is generics (parametric polymorphism). You can now define generic classes in JS++:

class Foo<T>
    /* ... */

Generic programming allows you to specify “type parameters” for a class. This allows you to create classes that can operate on any data type.

In version 0.8.0, JS++ supports the following generic programming features:

  • Multiple generic arguments
  • Multiple generic constraints
  • Inheritance (including generic from generic)

More advanced generic programming features (such as sound covariance/contravariance) are scheduled for upcoming releases.


While generics are a major feature, on a day-to-day basis, the official introduction of System.Dictionary<T> may be more important. Dictionaries are documented here and here. Dictionaries are also known as associative arrays, maps, etc.

Dictionaries allow you to create key-value pairs. The keys must be strings, but the values can be any data type.

import System;

Dictionary<unsigned int> ages = {
    "Steve": 25,
    "David": 31

Arbitrary key types will be possible in the future as we continue to expand the Standard Library. It’s going to be so much easier than JavaScript objects with non-string keys.

Multi-line Strings

This feature was available from the last release (0.7.0), but it wasn’t properly announced.

You can create multi-line strings with a syntax similar to Python’s:

string html =
    <!DOCTYPE html>
    <div id="notice the quotes are unescaped">some content goes here</div>

Multi-line strings are a useful way to create heredocs. One use case is pasting large blocks of HTML text that you don’t want to manually escape.


I consider this a critical class. If you understand the JS++ type system, you should understand the difference between “internal” types and “external” types. The BoxedExternal class basically allows you to construct an internal value (with an internal type) using any external value that has an external type.

When you box an external, it has an internal type. When you unbox the boxed external, you get a value with an external type. It’s extremely useful and is one way to achieve safe bi-directional communication between JavaScript and JS++.

Furthermore, if you’re using System.Object in your APIs, it becomes absolutely critical. Sometimes, you might want to define a function that can accept internal or external values.


This was a user request. The System.Benchmark class makes it easy for you to benchmark your code.

Here’s an example:

import System;
Benchmark bench = new Benchmark();

// ... do stuff
for (int i = 0; i < 500; ++i) {


It wasn't that this wasn't possible prior to the Benchmark class being introduced. It was just painful and unreadable. Remember: JS++ has an emphasis on code readability.

Dead Code Elimination (DCE) Improvements

In previous versions of JS++, dead code elimination (DCE) would not eliminate inherited methods. Since 0.8.0, the JS++ compiler supports DCE even in inheritance settings. This reduces the code size and footprint of the final output.

.js++ File Extension

Previously, JS++ supported the .jspp and .jpp file extensions. As of version 0.8.0, the JS++ compiler now officially supports the .js++ file extension too. When you input a directory to the compiler, it will automatically recursively search for .jspp, .jpp, and .js++ files now.

In order to support the new .js++ file extension, you may need to update your editor support.


This is probably the biggest release if you've been annoyed with the compiler warnings. We've completely suppressed the warnings for variable shadowing. JSPPW0015 and JSPPW0016 are gone. We're going to see how this goes or at least come up with saner rules before raising warnings. We've had applications internally that were raising hundreds of warnings on source code that otherwise compiled OK.

The #1 design principle here is that excessive warnings cause users to ignore warnings. Thus, we're being extra careful here.


  • System.Date copy constructor added
  • Binding on virtual methods
  • Removed System.Object.hashCode
  • Fixed segmentation fault for [].concat(1, 2, 3)
  • Fix segmentation fault for if(foo) where foo is an object
  • Fix closure capturing variable with name arguments
  • Don't cache .length of an array in for-in/each loops, to address potential array modification inside loops
  • Allow implicit conversion for double[] a = [1];
  • Forbid access modifier changes on override
  • Don't generate prototype chain for non-virtual methods
  • Lowest Common Ancestor (LCA) for expressions. This allows the type checker to deduce the type for arrays and dictionaries when polymorphism is present.

Looking Ahead

Expect Standard Library expansion and modifications.

We made changes to the original JavaScript API in our original Standard Library implementation. (Because whose great idea was it to introduce a String.substring and a String.substr in JavaScript?) We're likely going to restore the JavaScript API, and we're going to add data structures such as sets, maps, and more. We're also thinking about popular cryptography algorithms such as MD5, SHA1, and AES.

Meanwhile, generics will continue to be expanded and improved in future short-term releases.

Design Notes: Why isn’t System.Array.length an ‘unsigned int’?

It makes sense, doesn’t it? Array sizes should be unsigned because they can never be negative. Yet, JS++ chose to make System.Array<T>.length return a signed 32-bit integer (int). We’ve discussed this internally, and the underlying reasons are not so simple.


The most important reason is that this is a bug in JavaScript and ECMAScript 3’s original design. ECMAScript 3 15.4 specifies that Array#length is an unsigned 32-bit integer. However, it gets a bit tricky when you view these method signatures:

  • T[] Array#slice(int start) (ES3
  • T[] Array#slice(int start, int end) (ES3
  • T[] Array#splice(int startIndex) (ES3
  • T[] splice(int startIndex, int deleteCount) (ES3
  • T[] splice(int startIndex, int deleteCount, ...T replaceElements) (ES3
  • int Array#indexOf(T element) (ES5
  • int Array#indexOf(T element, int startingIndex) (ES5
  • int Array#lastIndexOf(T element) (ES5
  • int Array#lastIndexOf(T element, int endingIndex) (ES5

All of the above deal with array indexes as signed 32-bit integers even though the specification clearly states array lengths are unsigned. Specifically, if we indexed arrays using unsigned int, we would break JavaScript’s indexOf and lastIndexOf (because they return -1 when the element is not found). This gets further complicated because Array#push and Array#unshift, which return Array#length, return unsigned 32-bit integers.

Just know that I brought the proposal forward internally for indexing arrays as unsigned int, but I shut down my own proposal after the self-realization that it would break indexOf and lastIndexOf — it was just unacceptable.

In other words, we were handicapped by JavaScript in our design (as we often are).

Java and C#

A lot of website backends are written in Java, C#, PHP, and – nowadays – JavaScript. JavaScript and PHP are dynamically-typed, so you don’t have to worry about signed/unsigned, but this brings me to Java and C#.

Java doesn’t have unsigned integer types. I actually feel like this can be a good design decision in some ways. It makes reverse array iteration intuitive and obvious: just flip the logic for forward random-access iteration around. Likewise, in C#, List<T>.Count returns a signed integer (32-bit). Just as in Java, reverse iteration with a for loop is just flipping the logic around.

With signed integers, you don’t have to worry about integer overflow. If you perform forward iteration with:

for (int i = 0; i < list.Count; ++i);

Then, intuitively, reverse iteration might look like:

for (int i = list.Count - 1; i >= 0; --i);

Of course, this won't work for C/C++ because, on the final iteration, you get integer overflow.

Once again, in dynamic languages like JavaScript, you don't even have to worry about such things. It was all abstracted away by dynamic typing.

Reverse Array Iteration

Reverse array iteration over unsigned types becomes non-trivial. Anyone that has done this in C/C++ will know what I mean. The correct way to do it is to do it in a way that takes integer overflow into account. In C and C++, array sizes are unsigned, and C doesn't have C++ reverse iterators. Here's the code in C:

int arr[3] = { 1, 2, 3 };
size_t len = sizeof(arr)/sizeof(arr[0]);

for (size_t i = len; i --> 0;) {
    printf("%d\n", arr[i]);

So you initialize to the length of the array (without subtracting 1) and i --> 0 is better formatted as (i--) > 0. Thus, inside the loop body, you will only access - at most - length - 1 and it will count down until zero.

However, this isn't intuitive unless you come from a C/C++ background, and most C/C++ programmers are not web developers.


Reverse iteration in for loops may or may not be intuitive for you I didn't want users tearing their hair out over a basic programming exercise of iterating over an array backwards. Coupled with the fact that ECMAScript 3's original design was buggy, it only made sense to use int instead of unsigned int to avoid breaking old code from JavaScript.

Oh, and int is just so much more pleasant to type than unsigned int with casts everywhere.

JS++ 0.7.0: JavaScript Fully Implemented

JS++ 0.7.0 has arrived. Everything that is possible to do in JavaScript is now possible to do in JS++. JS++ has fully implemented JavaScript and the JS++ Standard Library is now fully documented.

This means that every JavaScript feature you expect is now available in JS++: arrays (0.7.0 introduces the generic Array<T> class), functions, date/time, regular expressions, loops, bitwise operators, etc. This is in addition to several JS++-only features: foreach, modules, classes, imports, enums, virtual functions, integer types, optimized auto-boxing, function overloading, dead code elimination (DCE), and so on.

You can find all the current Standard Library documentation by clicking here. Every documented class, method, and field (with examples) should be available and work in 0.7.0.


The major missing feature for a while now has been arrays. JS++ 0.7.0 brings the generic System.Array<T> class to JS++. With this addition, everything you can do in JavaScript is possible in JS++.

The full documentation for System.Array<T> is available here.

Additionally, JS++ adds more features to the Array API that aren’t available in JavaScript such as clear, contains, remove, first, last, count, and more. These methods are all optimized; in other words, there is no performance overhead in using them. In addition, we benchmark each method to make sure we are always providing the fastest implementation for an abstraction you want.

System.Array.sort and IComparable<T>

It comes as no surprise that JavaScript has strange behavior. Consider this JavaScript code:

var arr = [ 1, 2, 10, 9 ];
console.log(arr); // [ 1, 10, 2, 9 ]

As you can see, JavaScript did not sort the numeric array correctly. The reason for this behavior is because JavaScript performs a string sort regardless of the types in the array. Since JS++ is statically-typed, we can generate code for a correct sort with zero overhead. In JS++, the System.IComparable<T> interface provides exactly this behavior. If a class implements System.IComparable<T>, it can provide custom sorting behavior.

All Standard Library wrapper classes implement System.IComparable<T>. Thus, all JS++ numeric types will be sorted numerically when used inside an array – as you would expect from a modern, well-designed language. Here’s an example:

import System;

int[] arr = [ 1, 2, 10, 9 ]; // make sure you use an internal type like 'int[]' and not an external type like 'var'

And here’s the generated code:

// Compiled with JS++ v.0.7.0
! function() {
    ! function() {
        var arr = [1, 2, 10, 9];
        arr.sort(function(a, b) {
            return (a - b);

As you can see, there is zero overhead – despite the complex inheritance hierarchy (int[] being auto-boxed by System.Array<int>, System.Array<int> providing a custom sort based on generic type constraints, and System.Integer32 implementing IComparable<T>).

ECMAScript 5 Array Methods

ECMAScript 5 (ES5) added several array methods:

  • indexOf
  • lastIndexOf
  • every
  • some
  • filter
  • map
  • forEach
  • reduce
  • reduceRight

However, these methods are not supported in older web browsers. JS++ aims for enterprise support and legacy web application support. However, in order to polyfill these methods, it would result in hundreds of lines of code. Thus, in the spirit of JS++ dead code elimination (DCE), the above methods are only polyfilled for incompatible web browsers if and only if the individual method is used.


One peculiar Standard Library class you might notice is System.Object. Specifically, it does not implement the JavaScript API at all. This is because JS++ does not use prototypical inheritance like JavaScript does. JS++ uses class-based inheritance; thus, System.Object is minimal and does not provide methods that are only useful for a prototype-based language – such as hasOwnProperty and isPrototypeOf.

JS++ uses a “Unified Type System” (like Java/C#) with System.Object at the top of the inheritance hierarchy. Thus, System.Object represents all “internal types.” If you don’t know what that means, please fully read the “Getting Started” guide.

If you want to use JavaScript objects, you still have to declare external types until System.Dictionary<T> arrives:

var obj = {
    "a": 1,
    "b": 2

In addition, if you want the JavaScript Object prototype methods, use the Externals.JS module:

import System;
import Externals.JS;

Console.log(typeof Externals.JS.Object.prototype.hasOwnProperty == "function"); // true

Prefer the Standard Library

There are 300+ pages of Standard Library documentation (not including all the documentation for individual method overloads). This is in addition to 300+ pages of handwritten documentation, bringing the JS++ documentation to over 600 pages.

As always, I recommend that you prefer the JS++ Standard Library to writing your own JavaScript implementation. Consider clearing an array. In JS++, the code is:


You might be tempted to avoid the function call overhead and try to roll your own JavaScript:

arr = [];

First of all, this can create a memory leak (e.g. if other references to the original array are being held). The JS++ Standard Library provides high-quality, fast, and well-tested functions to you. Use it.

Secondly, what looks like function call overhead on the surface is actually inlined, correct code in the final output:

arr.length = 0;

Arrays have incredibly low overhead. Here’s the full code:

import System;

int[] arr = [1,2,3];

Here’s the generated output:

// Compiled with JS++ v.0.7.0

!function(){!function(){var arr=[1,2,3];arr.length=0;}();}();

As you can see, there is zero overhead. Thus, use the Standard Library. Don’t try to be fancy and write JavaScript rather than JS++ code. Your users’ garbage collectors will thank you for it in the future when you’re not leaking 500mb of RAM, and your team will thank you for it because .clear() is A LOT more readable than .length = 0 and A LOT more correct than arr = [];

Code Readability

One of the major driving changes for JS++ is code readability. We invest heavily into this from cutting-edge parsers to Standard Library design. The JS++ Standard Library allows you to write high-performance, readable code.

Consider this JavaScript code:

var abc = [ "a", "b", "c" ];
abc.splice(1, 1);

Without evaluating it, what do you think it does?

Here’s the equivalent JS++ code:

string[] abc = [ "a", "b", "c" ];

Same code. Same performance. Many times more readable when written in JS++.

Looking Ahead

We’re going to continue to expand the JS++ Standard Library to provide useful functions and give you a “batteries included” experience. Additionally, we’ll continue to expand the language. The following features are still not implemented:

  • User-defined Generic Classes
  • Reflection API
  • System.Dictionary (hash maps)
  • Block Scoping
  • Nullable Types
  • final variables (but final classes and methods are done)

If you have a pressing need for any of these features, you may want to wait. However, everything that is possible to do in JavaScript is now possible to do in JS++.

Compiler Architecture: Efficient Import Resolution for Context-Sensitive Grammars with Cyclic Dependencies

The JS++ programming language and compiler present unique engineering challenges. In my previous “Under the Hood” post, I discussed GLR parsing and disambiguation. Today, I will be discussing JS++ importing and the compiler architecture.

The JS++ import system efficiently supports features such as being decoupled from the file system and circular imports on an ambiguous context-sensitive grammar (CSG).

An example of tight coupling with the file system would be Java or ActionScript. If you define a class named utils.myapp.myclass, the file and directory structure would need to reflect this. This tight coupling presents problems during refactoring. If you change the name of a class or package/namespace, you would have to rename everything in the file system too. CommonJS, originally used by Node.js and RequireJS, suffered from a similar weakness.

When the import system is tightly coupled with the file system, resolving imports, modules, and files are an O(1) operation: just open the file based on its fully-qualified name. In JS++, resolving an import risks being an O(N2) operation where, for each import on each file, every other input file needs to be opened, parsed, and searched to find if a module was declared in the input file (or if the module was declared at all… in any input files).

In addition, JS++ faced an additional engineering challenge by enabling circular imports on an ambiguous grammar. Consider the following code:

Foo < bar > baz;

Is the above code a variable declaration to declare a variable named baz with type Foo<bar> or is it a comparison expression statement? Java and C# solve this ambiguity by simply restricting such “expression statements” from being statements to enable generic programming. However, JS++ inherited the JavaScript syntax, and it would not be ideal to have to break existing code and valid syntax that users already know.

The above code can be disambiguated if we know whether Foo is a generic class or not. If Foo is a generic class, the code is a variable declaration; otherwise, it is a comparison expression. This sounds simple in theory, but – in practice – what if Foo is declared in another module? Sure, you can import all modules first (and that comes with deeper questions such as what level of analysis or code generation do you want to perform prior to importing). However, the reality is not so simple. What if Foo is declared in another module, and we want to import it, but the other module has a circular dependency to the current file? Which one do we import first? How do we do all of this efficiently so that we don’t basically process a file more than once?

The JS++ compiler does not require you to specify the import and linking order during compilation. You can store all your *.jspp files in one directory and compile like so:

$ js++ .

There was no existing literature available. No existing language’s import system faced all the challenges that we faced (such as inheriting unorthodox semantics from JavaScript like function hoisting) or had the same design as we did. Internally, from an engineering perspective, we also wanted to reduce or eliminate “branching logic” in the compiler logic.

Thus, without the user specifying the import order, with circular imports on an ambiguous grammar being allowed, with no dependency on the file/folder structure, having to be compatible with JavaScript, and having to be as fast as possible (preferably without caching), how does the JS++ compiler do it?

Preface: The JS++ Import System

Users of JS++ can admire the ease of use. Unlike JavaScript, the JS++ import system is very simple:


module Utils.Strings
    bool isEmpty(string s) {
        return s == "";


import Utils.Strings;

isEmpty("");    // true
isEmpty("abc"); // false

The JS++ import system has several advantages to JavaScript’s:

Syntax and Brevity

First of all, you may immediately notice the conciseness. Prior to ES6, JavaScript had no modules and you had to use ad-hoc import systems. In ES6, when you define a module, you must explicitly declare the items you want to export. In contrast, JS++ will automatically “export” all your modules. The next thing you will notice is that JS++ also automatically imports all module members. In JavaScript, you would need to manually specify the specific members you want imported (or use a wildcard).


While JS++ may automatically “export” everything and subsequently “import” everything, it is very efficient. In a process known as dead code elimination, JS++ will “eliminate” unused code from the final output. For example, if your module defines three functions A, B, and C and you only use function A, then B and C will not be compiled in the final output. In addition, if you import a module but never use anything from the module, the entire module will simply not be generated.


Another benefit of the JS++ module and import system is simplicity. Consider all of the “overloads” of the ECMAScript 6 import keyword:

import * as myModule from 'my-module';
import {myMember} from 'my-module';
import {foo, bar} from 'my-module';
import {reallyReallyLongModuleMemberName as shortName}
  from 'my-module';
import {
  reallyReallyLongModuleMemberName as shortName,
  anotherLongModuleName as short
} from 'my-module';
import 'my-module';
import myDefault from 'my-module';
import myDefault, * as myModule from 'my-module';
// myModule used as a namespace
import myDefault, {foo, bar} from 'my-module';
// specific, named imports

Source: MDN

All of the above syntaxes do something different in JavaScript. In contrast, JS++ has only one import statement syntax:

import moduleName;


I once received a user question about why we don’t specify file/directory structure and naming conventions. The reason is because we give you absolute liberty here, and this actually comes from the software architecture. If you want your code to reflect the file/folder structure (a la Java), you’re free to do that. If you want all your code in one folder, you’re free to do that. However, we do specify a naming convention for modules in our documentation here.

Step 1. Parsing and Symbol Table Construction

The JS++ project is composed of several projects: the compiler, the parser, and so on. Prior to adding the import and module keywords in JS++ 0.4.2, the only project within JS++ using a symbol table was the compiler (for type checking). We began by decoupling the symbol table and refactoring it into a separate project as both the parser and compiler would depend on the symbol table.

Beginning from JS++ 0.4.2, the symbol table construction starts at parse time. Since the JS++ compiler allows you to use an entire directory as input (and it will recursively find all *.jspp and *.jpp files), we start by reading and parsing all input files. While we are parsing the input files, we build the symbol table and mark the symbols that cannot be currently resolved using a temporary meta-symbol such as <RELOCATE> or <UNRESOLVED>.

This process especially applies to “partially-qualified” names in JS++. This is what partial qualification looks like:

import Utils.Strings;

// Partial Qualification:
isEmpty("");    // true
isEmpty("abc"); // false

// Full Qualification:
Utils.Strings.isEmpty("");    // true
Utils.Strings.isEmpty("abc"); // false

In the above code, the identifier isEmpty can come from anywhere. It can even come from a module requiring circular imports. However, rather than processing the imports at this time, we simply mark the isEmpty identifier as unresolved for now. In addition, this allows us to deal with strange semantics that we inherited from JavaScript such as hoisting. In the case of hoisting, we might mark an identifier as unresolved even if it comes from the same file but gets declared later.

At this stage, the types of operations that may cause a symbol table insertion are “declarations” such as:

  1. Variable Declaration
  2. Function Declaration
  3. Function Parameter
  4. Module Declaration
  5. Label Statements (e.g. when labelling ‘for’ loops)
  6. Catch parameter (from try-catch blocks)
  7. External Statement (external foo;)
  8. Class and Interface Declarations (but this was not done for v.0.4.2)

At this point, no type checking or analysis has been performed. We only identified whether a symbol has been resolved or unresolved.

Step 2. Symbol Resolution

Once we have the basic symbol table built, we need to find all the symbols that need to be resolved and perform symbol resolution. However, we cannot haphazardly resolve symbols based on some “global” symbol table. This will lead to branching logic.

Instead, each resolution is file- and import-sensitive. In other words, we don’t process a “global” symbol table and resolve symbols. We process at the file level. We go through a file, and start by importing all modules based on import statements. Since JS++ imports by identifiers, you can see how finding an associated module or file can now be efficiently done without forcing the user into a Java-like import system that is tightly coupled to the file system.

Keep in mind that the same module “identifier” can be used across multiple files in JS++ because modules are not overwritten – they are “extended.” Nevertheless, it’s still just a symbol table lookup. (While building the symbol table, we can just “extend” the module’s sub-members each time a member is declared in a different file and keep information about which file each individual member is located to use for error reporting.)

Once the symbol is “found”, we replace the type in the symbol table from some unknown or <UNRESOLVED> type to the type of the symbol, and – in JS++ 0.4.2 – we record the pointer to its AST node for code generation (since we did not have an object code or intermediate language yet). If a symbol could not be resolved or if it could be found in one of the files but it wasn’t explicitly imported, we raise an error for undefined symbol.

Other errors that we can discover at this stage might be ambiguous partial qualification or cross-file, cross-module duplicate member declarations such as:

// A.jspp:
module Foo { void bar() {} } // Error, duplicate in B.jspp

// B.jspp:
module Foo { void bar() {} } // Error, duplicate in A.jspp

Step 3. Type Checking and Semantic Analysis

Since all symbols have now been resolved, we can perform type checking and semantic analysis.

At this stage, we don’t need to perform analysis in any particular file order. Thus, we do not need a topological sort (plus there is the chance for circular dependencies) or anything fancy. The JS++ compiler just uses the user-inputted file order here, but any order is fine.

Step 4. Dead Code Elimination

Once all analysis has completed, we also have information on which functions were called, which modules were used, which classes were instantiated. This allows us to perform dead code elimination and other optimizations.


While the problem itself was difficult and entailed many complexities, I’m happy that we were able to create a simple and efficient software architecture.

It might be possible that Java was tightly-coupled with the directory structure because of the engineering and architectural challenges involved in a more complex import system. For example, it should be clear that a custom parser is required, and a parser generator cannot be used. In a more complex grammar, there may be grammatical ambiguities involved. For example, the JS++ grammar cannot be described with a CFG or one-token lookahead. However, all these complexities were essentially covered and considered in the architecture.

In addition, circular imports need to be handled in a manner that is both time and space efficient. This article demonstrated how JS++ handles this without caching, without running a file through the full compile (or even parse) process more than once, and so on.

The JS++ import system is only one aspect of the JS++ compiler architecture. Even in languages that support circular imports, such as C#, they did not have to deal with JavaScript’s history. If you are interested in the challenges we faced in building on top of the JavaScript language syntax, consider reading my first “Under the Hood” series article about grammatical disambiguation.