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.

Generics

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.

System.Dictionary<T>

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>
    <head></head>
    <body>
    <div id="notice the quotes are unescaped">some content goes here</div>
    </body>
    </html>
    """;

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.

System.BoxedExternal

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.

System.Benchmark

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();
bench.start();

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

bench.stop();
  
Console.log(bench.duration);

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.

Warnings

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.

Miscellaneous

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

Roger PoonRoger Poon
JS++ Designer and Project Lead. Follow me on Twitter or GitHub.