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.

System.Array<T>

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 ];
arr.sort();
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'
arr.sort();

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.

System.Object

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:

arr.clear();

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];
arr.clear();

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" ];
abc.remove(1);

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++.