Smarter Javascript

One of the things I've been working on in my spare time is a reformulation of Javascript, so as to make it less squiggly. If you look at JS code, it involves far too much punctuation. All of the () and mixed in with . and , and : just makes for very busy code. It becomes hard to appreciate the quality of code with so much graphical noise breaking up a sentence. If you were trying to speak such code at a computer, you'd end up with a horrible parody of a Victor Borge routine. So what does this new Javascript look like?

An object named 'Device' plural 'Devices' from
dispatch:  action, event |  <br />       App widgets every { widget |  <br />                if (widget can action) widget.action event<br />

So what has changed? Well quite a bit. Here's the equivalent code in current JS:

An.object().named('Device').plural('Devices').from(<br />       dispatch : function(action,event) {<br />                App.widgets.every(function(widget) { <br />                        if (widget.can(action)) widget[action](event);<br />                );

This is already pretty clean for JS code in general, and because of how it is written can be evaluated within a single eval() statement. But if you compare the two listings, you can see how much of a difference a few punctuation marks can make. By changing the rules regarding how methods dispatches are designated in the language syntax, quite a bit of the structure of the language can be eliminated. So how do we get from JS as it stands today to this new nomenclature?

The effects of these changes are profound on how one writes code. Chaining methods is done through the mere aggregation of method names. Many of the more complex things you can do with dynamic dispatch are much more cleanly expressed. Additionally, strings, arrays, and objects function much more like functions, which take a value (integer in the case of strings and arrays, strings in the case of objects) and return a new value. And the style of programming morph greatly when one looks at lexical binding as a replacement for assignment. For example, let's say I want to replace an App object's delay value with a new one. What I would have typically writen is:

App.delay = 20;

The new formulation, however, would either use a binding operator or a property copying function which would copy the properties of an object passed to it:

App delay : 20

or as

App has delay : 20

You could write the same thing in existing Javascript using a function like:

Object.prototype.has = function(o) <br />   for (var k in o) if (o.hasOwnProperty(k)) this[k] = o[k];<br />  return this;<br />

App.has( delay: 20 );

The big win in this style of programming comes when you want to set a large number or properties at a time. For example, take the case of some graphical object properties. You may want to create a new rectangle with specific dimensions, at a particular coordinate in 3D space, and with a given RGBA color.

A rectangle has x : 100 , y : 200, z : 300 , width : 20 , height: 30, red : 255 , green : 0 , blue : 128, alpha :192

Using the formulation that works in existing JS you would write that using the above has method as:

A.rectangle().has( x : 100 , y : 200, z : 300 , width : 20 , height: 30, red : 255 , green : 0 , blue : 128, alpha : 129 )

But if you were more conventionally minded, you might have done the same thing but written code like:

var rect = new Rectangle();
rect.x = 100;
rect.y = 200;
rect.z = 300;
rect.width = 20;
rect.height = 30;
rect.red = 255;
rect.green = 0;
rect.blue = 128;
rect.alpha = 192;

which clearly shows a lack of appreciation for the finer points of language like Javascript. By reformulating how Javascript is parsed and perceived, quite a few of the fiddly bits can be removed. The resulting language is clean and conceptually elegant. Using some clever semantics, the code can be made much more humane and legible, with little harm done to its conciseness. By focusing on saying things the way you'd like to say them, rather than how you "have" to say it, you can both reduce the quantity of documentation necessary to make sense of the code, and increase the ease with which future programmers can read it.

Along those lines, I'm also toying with replacing the comment system // and /* / with requiring all lines of code start with a tab character, and that any lines that don't begin with a tab are removed as comments. The resulting literate javascript style looks something like this:

Draw a rectangular button at (100,200) that if clicked, confirms that the registration information is correct.

A rectangle named 'button' has x : 100 , y : 200, width : 200 , height: 30, src : 'button.png',
down: { event | if (event on this) document goto '/confirm?value=true' }

Since we can include JS code using AJAX at runtime, it is easy enough to load our code written in this format, parse it, and re-synthesize it into ordinary JS on the fly. The small upfront cost of performing a rewrite on the client side can also have long lasting benefits, especially in the case of long running JS applications. By allowing us to write documentation inline like this, and stripping out the code based on indentation, it reduces the likelihood that documentation and code will get out of sync. It also encourages developers to keep better notes of what they are doing, and avoid doing silly things like:

this.id = 'foo'; // set the id of the HTML element to 'foo'
this.style.display = 'none'; // hide the element by setting its CSS display property to none.
} // end of function
} // end of if

These sorts of comments are merely meaningless lip service to the idea of documenting your code, and yet they tend to be the norm whenever code gets commented. When the code changes, these comments tend to get messed up, especially if a comment spans multiple lines, and the resulting change is not reflected in the comment. The "end of function" vs "end of if" block comments above are indicative of this sort of sloppiness, and is found all to commonly in production code.

Hopefully, over the next couple weeks, as the parser get cleaned up and finalized, I'll release a version of it on Github, with sufficient examples of how the new syntax can encourage better OO technique, and improve the legibility and semantics of your code