Scratching the surface of JS++

The problems

Dynamic typing is great! It is basically the function overloading of Javascript. You can define APIs that allow users to use your module as they’d like. You can switch between passing a string for some default behavior or a complex configuration object if you need to set things up in detail. But there’s also a catch. Take a look at the following case from Lodash:

Maintaining an API this way can make your code convoluted and hard to read. Your find method has to check if the user’s argument is an Array or an Object and you also have to handle several ways they can identify your target item. This means the method will be full of conditions which can make the code hard to read and slower runtime. This is only one problem, as the other problem surfaces when you check the documentation for this method:

It’s not rocket science, you’ll either get your element or undefined. Why is that a problem? If we look at our Lodash example method find, we can easily produce some issues. Please consider the following:

Because what if Waldo ain’t there? We have to check the result of our search, make sure it’s a string, and ensure at least it has the toUpperCase method defined, to avoid this error. That can be tiresome, and does not really add to value when it comes to readability but it can bring your server to its knees with something trivial.

Also, what if the documentation lies, or you have a case, where the list you search in contains something unexpected (for example, instead of Waldo you need the first name that is longer than 3 letters)?

Because you have an array, which does not expose the toUpperCase method, you’ll get a type error. There are several ways to overcome this of course, but you need to handle them each time, pausing the reader to figure out the safeguard you have in there every time.

So how can we overcome this? We can write the following code in JS++:

And the issue is avoided. No additional checks or explicit conversions to handle. Just the logic you are interested in.

To address the first problem, overloading comes with JS++. This gives you the possibility to keep your code readable by avoiding checking the types inside the logic of your flexible API.

The concept

JS++ is a superset of Javascript, which allows for a more strict handling of types, to ensure fewer runtime errors. It implements runtime type conversions for the built-in data types, and also creates a barrier between the code you’ve written in JS++ and the outside. Because it’s a superset, your plain Javascript is still valid!

If we look at the previous code example, we can notice a few things, which helps to clarify what I’ve just said. You can observe a new keyword external. This tells the compiler that the resource we defined as external does not need to be checked because it comes from the “danger zone”. The compiler lets developers use whatever library he/she wants, and only acts as soon as the JS++ and Javascript barriers meet. That happens in this line:

We do not know what comes out of the find method. We assume it’s a string, so we assign it to a string variable. And this is the point where JS++ kicks in. It guarantees you that name will always be a string, no matter what it was originally. It handles all conversions. But you’ll only need to convert the external sources. Once you are in the “safe zone”, the compiler can track and check what you did, and it won’t let you run the code until all errors have been fixed.

This certainty is what people look for in any typed language, as opposed to Typescript for example and it’s concept of the any keyword. One of our example codes in TS would be like:

Typescript not only turns off checking, but it will not make sure that your name is truly a string. You might also have a type definition file in place for the Lodash lib, but that’s not checked against anything! It just describes how it should work, but lets you down during execution.

For more info on type conversions built in, please go through the documentation on this:

The syntax

The first thing that grabbed my attention when I landed on Onux’s website was the syntax of JS++. Familiar, simple, readable. Is this really Javascript? This is the question I asked myself. Although the site went through an update since then, it still welcomes you with a snippet of code which doesn’t look like Javascript initially until you read it through.

The syntax borrows elements from the well-known and established languages like C, C++, Java and C#. This allows you to get rid of the colon after the variable names and allows you to read the code more efficiently while keeping type information. I think it is easier on the eyes and mind too. Let me illustrate as Typescript or Haxe would like you to say:

We have a variable called Foo — which is a number — and has the value of 42.

As opposed to the JS++ dialect:

We have an integer called Foo, with the value of 42.

I find my mind parses it faster, because it does not add bloat by stating the obvious, and is even more precise by differentiating integers and bytes for example! You probably can guess the two lines in code, even if you are not very familiar with the aforementioned languages:

Typescript vs JS++ syntax defining variables.

This difference may seem superficial, but for me (and maybe for others too), who came from Javascript and before using strictly typed languages — like the aforementioned Java or C# —it feels like:

Feels clean

A quote from Roger Poon that summarizes it:

In a nutshell: the colon syntax is easier for the compiler writers and harder for the developers, and the traditional C syntax is harder for the compiler writers and easier for the developers. ~Roger Poon

I recommend you to read the full article on the challenges of writing a compiler that makes syntax like this possible for Javascript:

Final thoughts

I’m very much in favor of this endeavor! It’s safer, which is a concern in production. It’s cleaner, as it allows more freedom on coding style, allowing you to write less and achieve more.

And have you thought about porting your whole code for example? You don’t need to, not one time!

The internal-external paradigm, with conversions, makes gradual porting possible. You can port some of your logic and still use JQuery for example. You just declare it as an external JQuery, $; and you are ready to go in the browser.

There are still milestones to achieve for the team at Onux like implementing the full class system as described in the docs or implementing the DOM API and System library for Node in JS++. And they’re doing just that, and fast, so stay tuned, calm and subscribe to the newsletter:

or follow the news section: