V8-GL

I’ve been doing a couple of changes to the JavaScript InfoVis Tookit lately, which I’ll describe in some other post, but most important I’ve been working on a new project I’m really excited about that’s called V8-GL.

What’s V8-GL?

V8-GL intends to provide a high-level JavaScript API for creating 2D/3D hardware accelerated desktop graphics.

In other words, you can hack some JavaScript code that opens a desktop window and renders some 3D hardware accelerated graphics. Bindings are made using the V8 JavaScript engine.

Example

I wrote a small example that animates a rotating Icosahedron. This example uses timers, colors and lighting among other things:

//Add array iteration method
Array.prototype.each = function(f) {
	var len = this.length;
	for ( var i = 0; i < len; i++) f(this[i]);
};

//Initializes 3D rendering
function initRendering() {
	"DEPTH_TEST COLOR_MATERIAL LIGHTING LIGHT0 NORMALIZE COLOR_MATERIAL"
		.split(" ").each(function(elem) {
		Gl.Enable(Gl[elem]);
	});
}

//angle variable
var angle = 0;

//Draws the 3D scene
function drawScene() {
	//Set global color and drawing properties
	Gl.Clear(Gl.COLOR_BUFFER_BIT | Gl.DEPTH_BUFFER_BIT);
	Gl.MatrixMode(Gl.MODELVIEW);
	Gl.LoadIdentity();
	Gl.Translatef(0.0, 0.0, -5.0);
	//Set diffuse and positioned lights
	Gl.LightModelfv(Gl.LIGHT_MODEL_AMBIENT, [0.3, 0.3, 0.3, 1.0]);
	Gl.Lightfv(Gl.LIGHT0, Gl.DIFFUSE, [0.4, 0.4, 0.4, 1.0]);
	Gl.Lightfv(Gl.LIGHT0, Gl.POSITION, [5.0, 5.0, 5.0, 1.0]);
	//Rotate and plot Icosahedron
	Gl.Rotatef(angle, 1.0, 1.0, 1.0);
	Gl.Color3f(0.5, 0.0, 0.8);
	Glut.SolidIcosahedron(2.5);
	//Render
	Glut.SwapBuffers();
}

(function() {
	//Initialize Glut
	Glut.Init();
	Glut.InitDisplayMode(Glut.DOUBLE | Glut.RGB | Glut.DEPTH);
	Glut.InitWindowSize(400, 400); //Set the window size
	//Create the window
	Glut.CreateWindow("OpenGL on V8 baby!");
	initRendering();
	//Set drawing callback
	Glut.DisplayFunc(drawScene);
	//Set resize window callback
	Glut.ReshapeFunc(function(w, h) {
		var gl = { 'Viewport': [0, 0, w, h], 'MatrixMode': [Gl.PROJECTION], 'LoadIdentity': [] };
		for (var i in gl) Gl[i].apply(this, gl[i]);
		Glu.Perspective(45.0, w / h, 1.0, 200.0);
	});
	//Set timeout callback
	Glut.TimerFunc(25, function() {
		angle += 2.0;
		if (angle > 360) angle -= 360;
		Glut.PostRedisplay();
		Glut.TimerFunc(25, arguments.callee, 0);
	}, 0);
	//Start the main loop.
	Glut.MainLoop();
})();

OpenGL devs. might recognize the API exposed through the Gl, Glu and Glut objects.

Status

Currently 80% of the OpenGL API is implemented. OpenGL APIs are exposed through the Gl, Glu and Glut global objects.

However, like I said before, this project is not just about making OpenGL bindings for JavaScript through V8, but to provide a higher level API.

Although this project is in current development you can already clone the repo and follow the Download instructions at the V8-GL project page for creating some cool examples.

Hope you like it :)

The JavaScript InfoVis Toolkit 1.1 is Out!

After several months of hard work I can finally announce version 1.1 of the JavaScript InfoVis Toolkit.

What’s the JavaScript InfoVis Toolkit?

The JavaScript InfoVis Toolkit provides tools for creating Interactive Data Visualizations for the Web.

What’s new in this version?

Code-Related

  • The library has been split into modules for code reuse.
  • All visualizations are packaged in the same file. You can create multiple instances of any visualization. Moreover, you can combine and compose visualizations. If you want to know more take a look at the Advanced Demos.
  • This Toolkit is library agnostic. This means that you can combine this toolkit with your favorite DOM/Events/Ajax framework such as Prototype, MooTools, ExtJS, YUI, JQuery, etc.
  • You can extend this library in many ways by adding or overriding class methods. The JavaScript InfoVis Toolkit has a robust (and private) class system, heavily inspired by MooTools’, that allows you to implement new methods in the same class without having to define any new Class extension. By creating mutable classes you can add new custom Node and Edge rendering functions pretty easily.
  • Custom visualizations are created by adding or changing Node/Edge colors, shapes, rendering functions, etc. You can also implement many controller methods that are triggered at different stages of the animation, like onBefore/AfterPlotLine, onBefore/AfterCompute, onBefore/AfterPlotNode, request, etc.
    You can also add new Animation transitions like Elastic or Back with easeIn/Out transitions.
    If you want to know more about these features please take a look at the Demos code.

As you can see, this new version has been built with four concepts/goals in mind: Modularity, Customization, Composition and Extensibility. I already explained some of these things in the previous post.

Hope you enjoy it.

More about the JavaScript InfoVis Toolkit 1.1

I’ve been putting a lot of effort in the upcoming version of the JavaScript InfoVis Toolkit lately, and I though it would be a good idea to show some of the new features I came up with.

The new version isn’t finished yet, but I’ve come pretty far and wanted to make a sort of checkpoint for the things I’ve done, the things I’ll be doing and the things I’m thinking about doing.

So what have I been working on?

  • A new project page design.
  • A complete documentation. I made an API documentation that is also mixed with some narrative documentation for each Class, so you can learn how the visualizations are implemented and how to use them.
  • Packaging All visualizations will be packaged in the same file, and you’ll be able to make your own build based on what you’re going to use (Treemaps, Hypertrees, RGraphs, Spacetrees or any combination of those). This is a cool aspect of making modular code.
    The other good thing about modular code is that the size of the full package will drop in ~30% compared to version 1.0.8a
  • Examples I’ve been coding some new visualization examples that will be packaged with the library. Some of them are very similar to the ones found in 1.0.8a, but adapted for version 1.1. Other examples show some of the new features of the library, and others try to expose some features of version 1.0.8a that were not properly documented.

Library features

I’ve been building this library with four things in mind:

  • Extensibility The library has multiple access points where it can be extended in different ways. For example, all main Classes are mutable objects, so you can extend or implement any method of any class in-place, like for example re-implement the nodes coloring method in the Squarified treemap:

       //TM.Strip, TM.SliceAndDice also work
       TM.Squarified.implement({
         'setColor': function(json) {
           return json.data.$color;
         }
       });
    

    …or adding new node/edge plotting methods in the Hypertree, ST or RGraph:

    Hypertree.Plot.NodeTypes.implement({
      'my-node-rendering-method': function(node, canvas) {
        //implement node rendering here
      }
    });
    

    etc.

  • Customization The library provides many ways for customizing the visualizations. There are controller methods that determine the behavior of the visualization, and configuration parameters like node and edge types, color and dimensions. Node shapes can be square, rectangle, circle, ellipse, etc. and edge shapes: line, hyperline and arrow. I also added transition effects like Quart, Bounce, Elastic, Back, etc. for the animations.
  • Modularity As explained above, the code has been divided into modules, providing a way for making custom builds of the library. Modularity also takes care of namespacing: I only add Classes that are meant to be accessed by the user and I don’t pollute the window object with unnecessary global objects.
  • Composition A major improvement in this version is that all visualizations can co-exist in the same namespace. That means that multiple instances of different visualizations can be used and composed to make new visualizations. I haven’t explored this feature of the library yet, but this would mean that for example I can make a Treemap that has Hypertrees rendered as leaves, or a Spacetree that has Treemaps as nodes, or… well, any other combination of things.

Examples

As you might know, I don’t have the most suited computer for making screencasts, so sorry if you see some performance problems.

This is a short video I made of a RGraph example.

The main idea behind this example is Customization.
That can be seen for example in the different node types, edge types and colors used, as well as in the Elastic transition effect for the animation.

This is just an example to expose as much features as I can in one visualization, so don’t take this as a “useful” visualization example please.

Here is another short video: it illustrates how Graph Operations can be made with the Hypertree visualization.

You’ll see 4 consecutive operations:

  1. Removing a subtree The bottom right subtree will be removed with an animation.
  2. Removing edges Edges from the top left subtree will be removed with an animation.
  3. Adding a graph A graph will be added with an animation
  4. Morphing The graph will transform into another graph -with an animation

Enjoy.

Interactive Visualization of Genealogical Graphs

It’s been a while since I last bumped into a nice visualization project like this one.
It offers an advanced interface for exploring Genealogical graphs.

I personally like how nodes are hidden/shown in demand, how the subtree widget is implemented and how you can easily switch between different layouts.

On a side note, I’ve been screencasting the artist/band visualization project I made some time ago with the JavaScript InfoVis Toolkit, hope you find it interesting: it shows relations between artists and bands by collaborations in albums/songs/bands, etc.

You can access a live example here. I think its better rendered with Firefox, Safari, Opera and Chrome 2 (version 1.0.x has a bug).

The left menu offers some navigation options to choose a band as starting point. You can also find details about the focused band under the Details toggler.

Here’s a short video of what you should be able to see:

Taking a look at Groovy

While at work last week I decided to make a small program in the Groovy programming language. I needed to build a small file processing program that used some Java libraries built at work, but I didn’t want to code five or six Java classes to do so. Since performance wasn’t a big concern, I decided to take a look at some JVM based languages.

There are lots of programming languages targetting the JVM, so why Groovy?

Why Groovy?

Groovy is a highly dynamic language, that takes things from Python, Ruby and Smalltalk. Since these are programming languages I used before and I’m quite comfortable with, Groovy seemed like a good match.

Also, Groovy is very easy to learn, having an almost-zero learning curve. Since I had to do this in a couple of days, I didn’t want to spend a lot of time learning a programming language’s syntax and semantics. I know how to use Python and I know how to use Ruby/Smalltalk, I just want to do the same things in the JVM.

Another very interesting thing (that doesn’t concern the language itself, but it’s quite helpful) is that Groovy, along with OCaml and Perl, has a 100% completness score at PLEAC. That means that you can find complete examples of: Strings, Numbers, Arrays, Hashes, Dates and Times, Pattern Matching, File Access, File Contents, Directories, Subroutines, References and Records, Packages, Libraries and Modules, Classes and Objects, Database Access, User Interfaces and a lot more here.

Features I like about the language

Some of the features I used and liked about Groovy:

List and Hash literals
As opposed to Java, Groovy provides List and Hash literals:

//Create an empty List
emptyList = []
//Create an empty Hash
emptyHash = [:]
//Create a List
somePeople = ["John", "Jack", "Sarah"]
//Create a Hash
ext = [
  Ruby: 'rb',
  Python: 'py',
  C: 'c',
  Groovy: 'groovy'
]

List and Hash traversing and manipulation

In terms of List and Hash manipulation, Groovy offers the same expressiveness as Python and Smalltalk:

//Create a List
somePeople = ["John", "Jack", "Sarah"]

//Copy first two List elements
copy = somePeople[0..1] //["John", "Jack"]

//Grab last list element
lastElem = somePeople[-1] //"Sarah"

//Closures are first class values in Groovy, their syntax is {}.
//For unary lambdas an implicit 'it' variable is created

//Any element starting with capital letters?
somePeople.any { it[0] in 'A'..'Z' } //true

//We can also use regex a la Perl
somePeople.any { it =~ /[A-Z].*/ } //true

//Print names with new lines
somePeople.each { println it }

//Create a Hash
ext = [
  Ruby: 'rb',
  Python: 'py',
  C: 'c',
  Groovy: 'groovy'
]

//print an element
println ext.'Ruby' //rb
println ext['Ruby']//rb

//iterate through a hash elements
ext.each { key, value -> println key + ': ' + value }
//will print Ruby: rb, etc

Defining functions
Functions are defined like this:

//Define a square function
def square(val) {
 val * val
}

//Or assign a closure to a square variable:
square = { it * it }

Simple.

Java classes extensions
One of the things I find really nice about Groovy, is that it extends Java SE with useful functions.
You can find the extensions here.

Java File class extensions are pretty cool:

//Print dir file names
new File("/some/dir/").eachFile { println it.name }

//Print file text content
println new File("/some/file.txt").getText()

//Print file content with line numbers
new File("otherfile.txt").eachLine { it, line -> println line + ": " + it }

Other libraries

At work I had to deal with XML data, and found a very interesting and high level XML manipulation library called XmlSlurper:

xml = ‘‘‘
<root>
<artist name="Pearl Jam">
  <album>Ten</album>
  <album>Vs.</album>
  <album>Vitalogy</album>
  <album>Riot Act</album>
</artist>
<artist name="Soundgarden">
  <album>Down on the Upside</album>
  <album>Superunknown</album>
</artist>
</root>
‘‘‘
root = new XmlSlurper().parseText(xml)
root.artist.each {
  println it.@name.text() + ': ' +
        it.album.collect({ it.text() }).join(', ')
}
//Will print
//Pearl Jam: Ten, Vs., Vitalogy, Riot Act
//Soundgarden: Down on the Upside, Superunknown

Conclusion

Groovy is a versatile scripting language built on top of the JVM.
It provides useful features taken from Ruby, Python and Smalltalk, with full access to all Java libraries.
It also extends Java classes with useful methods and iterators.
If you aren’t that worried about performance (still runs faster than Ruby, Python 3 and Perl), I’d recommend you to take a look at it.
Hope this was helpful enough to get a feeling of the language.

JavaScript InfoVis Toolkit 1.1 Preview

In case you’re wondering what I’m up to…

I’ve been adding more features to the JavaScript InfoVis Toolkit, to be released I-don’t-know-when-yet (still a lot of work to do regarding documentation, hosting, scripts, etc.).

Anyway, this video shows only some of the features to be included:

  • Custom nodes: built-in shapes are none, circle, square, rectangle, ellipse, among others
  • Custom edges: built-in shapes are none, line, quadratic, bezier, arrow, among others
  • Custom Animations: linear, Quart, Bounce, Elastic, Back, etc.
  • Change tree orientation: already possible in 1.0.8a.

Unfortunately my video card isn’t very good, so the video quality and fps aren’t as good as I’d wanted.
Animations are pretty smooth though, as you can see for yourself, so don’t blame the library, blame my computer!

Anyway, here’s the video:

Another cool thing is that you can also create custom node and edge rendering functions :)

Stay tuned, there are more features to come!

Sharp Variables

I was looking for some way to easily create, read, manipulate and print cyclic or recursive data structures in some programming languages, and got to the cool concept of sharp variables.

Manipulating Recursive Structures in Python

A straightforward way of defining a recursive structure is to first assign a base (non-recursive) structure to a variable, and then alter or extend that variable with a recursive expression. For example, in Python you can write:

my_rec_var = [1, 2, 3]
my_rec_var.append(my_rec_var)

That code will create a recursive data structure: [1, 2, 3, [1, 2, 3, [...]]],
or a = [1, 2, 3, a].

Actually, Python’s print function lets you print a representation of a recursive structure without recursing indefinitely:

>>> print my_rec_var
[1, 2, 3, [...]]

Python’s pickle module lets you dump a recursive data structure into a file. You can also read that serialized structure from the file:

import pickle

#dump it to file
output = open("out.pkl", "wb")
pickle.dump(my_rec_var, output)

However, there’s no literal way of creating, reading or modifying that structure:

>>> my_rec_var = [1, 2, 3, [...]]
 ERROR

Manipulating Recursive Structures in Lisp

For manipulating/printing recursive data structures in Common Lisp we first assign T to the global variable *print-circle*

(setq *print-circle* T)

We can define a recursive structure just as we did with Python, by defining some base structure and then modifying the structure to be recursive:

(defvar *my-rec-var* (list 1 2 3 _))
;Replace the underscore placeholder with a self-reference
(setf (fourth *my-rec-var*) *my-rec-var*)

The final structure is represented with sharp variables:

>>> (print *my-rec-var*)
#1=(1 2 3 #1#)

This is just as the “Mathematical” definition we gave above:
a = [1, 2, 3, a].

What’s interesting about this “serialization format” is that expressions involving sharp variables are truly expressions: these “objects” can be read and manipulated just like any other structure:

>>> (defvar *another-rec-var* ‘#1=(1 2 3 #1#))
#1=(1 2 3 #1#)

>>> (fourth ‘#1=(1 2 3 #1#))
#1=(1 2 3 #1#)

>>> (cons 5 ‘#1=(1 2 3 #1#))
(5 . #1=(1 2 3 #1#))

Sharp variables seem like an excellent solution for creating, reading and manipulating cyclic data structures.

Sharp Variables in JavaScript

Mozilla’s JavaScript implementation has Sharp Variables. They’ve been introduced by Brendan Eich and they are inspired by Common Lisp’s syntax.
Sharp Variables can be pretty useful in JavaScript, since most of the time we’re manipulating object references and Firefox’s toSource() method is pretty useful for debugging (among other things).

var myArray = [1, 2, 3];
myArray.push(myArray);
myArray.toSource();

Try running that in your Firefox console, it should return “#1=[1, 2, 3, #1#]“.

Oh, and did I mention that you can also explicitly manipulate cyclic structures in JavaScript?

//Assign a literal recursive data structure
var anotherArray = #1=[1, 2, 3, #1#];

console.log(anotherArray.toSource());
//"#1=[1, 2, 3, #1#]"

console.log(anotherArray[0]);
//1

console.log(anotherArray[3].toSource());
//"#1=[1, 2, 3, #1#]"

I was happy to find such an interesting Lisp feature in JavaScript.

Generic Functions and JavaScript

In my last post I mentioned Operator Overloading, and why I think it would be interesting to see this as a proposal for the ECMAScript 4 specification (the new JavaScript specification).
I’ve been following the ECMA discussion list and the ES 4 wiki, and I was surprised to see that I feel the same way as some people in the ECMA group do about operator overloading.
The Operator Overloading proposal has been made a couple of times before, but it was disregarded as beeing too weak to be considered.

However, this proposal has been superseeded by some other (very interesting) proposal: generic functions (a.k.a multimethods).

What are generic functions?

The first time I discovered generic functions was while playing with Common Lisp’s Object System (CLOS).
In fact, early Lisp systems worked as Smalltalk did, by implementing a send function:


(send object :foo)

instead of just doing:


(foo object)

They finally came with the solution of creating generic functions that could be implemented by methods. This design is far more expressive that the classic OO design, implemented in languages such as Java.
Since this design is far from classical OO ones, explaining by example turns out to be quite difficult: the wikipedia examples aren’t very enlightening (see the article’s discussions).

So here I go.

Java has function overloading: that means that several methods with the same name can be defined in the same class, provided that the type (or number of arguments) defined in each method is not the same.

So, for example, lets define a Java class Person with two eat methods:

  class Person {
    public void eat (Food f) { println ("eating food"); }
    public void eat(Pasta p) { println ("eating pasta"); }
  }

(Pasta extends Food)

We have succesfully overloaded the eat method. However, the overloading happens at compile time, and there’s no dynamic dispatch. So, for example this code:

  Food food = new Pasta();
  somePerson.eat(food);

Will answer “eating food”, which isn’t exactly what we want.

Now lets consider this code:

class John extends Person {
    public void eat(Food f) { println ("mmm...."); }
    public void eat(Pasta p) { println ("Yummy!"); }
  }

  Person me = new John();
  Food pasta   = new Pasta();
  me.eat(pasta);

This code will answer “mmm…”. But there’s one important thing: we’ve called a method from John’s class, instead of some eat method from Person.

This had to be decided at run time, since me is of type Person, but we assigned a John to it…

Now lets define, in pseudo-code, an abstraction of these eat methods, that could be thought as decoupled from the John and Person classes. For example, we could re-write John and Person eat methods as four independent functions:

public void function eat(John john, Food f) { ... }
public void function eat(John john, Pasta p) { ... }

public void function eat(Person person, Food f) { ... }
public void function eat(Person person, Pasta p) { ... }

What we know about these methods is that Java checks its first argument type at runtime, but all other arguments are checked at compile-time.
So, as far as dynamic dispatch concerns, Java has single dispatch, and function overloading only refers to compile-time checked types, which in general doesn’t yield the expected result. (This problem beeing solved by the visitor pattern in most cases).

A generic function can be seen as a family of functions that provide multiple dispatch, that means that all arguments of the function are checked at runtime (on invocation). Not only the first argument, but all.
Compared to Java, this approach would, in most cases, yield the expected answers without having to implement some patterns like the visitor pattern.

The four methods defined above could be redefined in CLOS as:

(defmethod eat ((john John) (f Food)) ... )
(defmethod eat ((john John) (p Pasta)) ... )

(defmethod eat ((person Person) (f Food)) ... )
(defmethod eat ((person Person) (p Pasta)) ... )

Generic Functions in JavaScript

The Generic Functions JavaScript proposal aims to solve all weaknesses existing in the Operator Overloading proposal, but it also provides a more generic way of defining and manipulating functions.
Operator Overloading should be seen as a particular case of what can be done with generic functions in JavaScript.

In JavaScript, a generic function could be defined as:


generic function f(x, y);

Since a generic function defines a family of functions, there’s no function body in it.
A generic function can also be defined with type annotations:


generic function f(x: Numeric, y: Object): MyClass;

A method is then defined over an existing generic function, using specializers:


 generic function f(x:int, y:boolean): string {
      if (y)
          return string(x);
      else
          return "37";
  }

Eventually, built-in generic functions could be defined for common operators, providing a way of overloading operators:


generic function +(a:Complex, b:Complex) {
   return new Complex(a.x + b.x, a.y + b.y);
}

For a JavaScript canvas developer, this would be wonderful, since we mess with Complex, Polar, Matrix classes all the time, and a simple interpolation expression of two complex numbers could be transformed from this:

(to.$add(from.scale(-1))).$scale(delta).$add(from)

into this:


from + (to - from) * delta

Cushion Treemaps

Remember Treemaps?

There was a thread at the Google Group for the JIT asking for Gradients in Treemaps.

Actually they’re called cushion treemaps, and they have been created by Ph.Ds Jarke J. van Wijk and Huub van de Wetering. Cushion Treemaps have been used in successful applications like SequoiaView and companies like MagnaView are building very interesting visualizations with cushion treemaps.

The paper is quite interesting: cushion treemaps were created by using shading to show a tree’s structure:

“How can we use shading to show the tree structure? The human visual system is trained to interpret variations in shade as illuminated surfaces [6]. Hence, we can answer the question by constructing a surface which shape encodes the tree structure.”

Shadowing is created by adding bumps to rectangles.

In the JavaScript InfoVis Toolkit, this can be done by overriding the leafBox method of the Treemap class. This method renders a leaf node (nodes which are generally colored in the Treemap).
By adding an image of a radial gradient inside that div we can emulate cushion treemaps.

Instead of creating a new class that extends TM and overrides that method, we can take advantage of JavaScript’s object mutability feature and re-implement the method in the same class.


    TM.Squarified.implement({
       leafBox: function(json, coord) {
        var config = this.config;
        var backgroundColor = config.Color.allow && this.setColor(json),
        offst = config.offset,
        width = coord.width - offst,
        height = coord.height - offst;
        var c = {
         'top': (offst / 2) + "px",
         'height':height + "px",
         'width': width + "px",
         'left': (offst / 2) + "px"
        };
        if(backgroundColor) c['background-color'] = backgroundColor;
       //Add an image to our leaf node to create a cushion treemap.
        var img = "<img src='gradient.png' style='position:absolute; z-index:2; top:0; left:0; width:" + c.width + "; height:"+ c.height +"'; />"; 

        return "<div class='leaf' style=" + this.toStyle(c) + ">" + img + json.name + "</div>";
       }
    });

And that’s it, now we have Squarified Cushion Treemaps. I must say that I love cushion treemaps, they look a lot more cool than simple treemaps.

I made a small POC where you can enable/disable the cushion feature, among other interesting things:

cushion treemap

Why not Operator Overloading in JavaScript?

Disclaimer: Some of this post arguments are inspired by the great talk by Guy Steele: Growing a Language.

So I was checking out the new JavaScript spec. (ECMAScript 4) lately, and I was very surprised (and disappointed) to see that Operator Overloading wasn’t even accepted as a proposal for ECMAScript 4.
I’ve noticed last year that the proposal was denied by all browser vendors, as you can see in the ECMAScript 4 progress spreadsheet created by John Resig, under the name of “Operator Overloading”.

This is heartbreaking for me… let me explain you why.

Why Operator Overloading (in general)?

Operator Overloading is a special case of polymorphism, in which operators like +, /, *, … can be overloaded by the user.
This is very useful in languages where the user can define special types (or classes), since it allows the developer to use notation that is closer to the target domain, and allows user types to look like types built into the language.

What Guy Steele said about Operator Overloading is that:

“If we grow the language in these few ways, then we will not need to grow it in a hundred other ways; the users can take on the rest of the task.”

To see why, think about these structures:

  • 2D, 3D Vectors
  • Matrices
  • Intervals
  • Complex Numbers
  • Polar Coordinates
  • Rational Numbers

One thing all these structures have in common is that their sum and product operations have a different definition than the one we give to integers.

There’s also an interesting fact about these structures: a lot of people use them, but a lot of people don’t.
For example, Matrices might be used by OpenGL/Direct3D developers, but it’s not very common to use this structure for manipulating the DOM or building AJAX applications.

However, each of these structures must be considered in any programming language.
Adding them all into some standard library might be too much. However, sooner or later, some developer will want to use them.

Here’s the dilemma as exposed by Guy Steele:
I might say “yes” to each one of these, but it is clear that I must say “no” to all of them!“.

Operator Overloading solves this problem by giving the user the power to overload built-in operations and turn a non-domain specific language into a perfect tool for a developer’s specific needs.

By using Operator Overloading a developer can define operations on any custom type and its use will blend perfectly well into the language.

Wouldn’t be just beatifull if a and b beeing Complex Numbers, we could do this:

a + b * c

instead of this? :

add (a, multiply (b,c))

Ok, so now that I made my point about the power of operator overloading, let me explain you why I think this should be more carefully considered by the new JavaScript spec.

Why Operator Overloading in JavaScript?

To see why we should take seriously Operator Overloading in JavaScript, we first have to take a look at what happened to JavaScript in the last few years.

Only one thing happened to JavaScript in the last few years, AJAX.

The XMLHTTPRequest concept was first created by Microsoft, and wasn’t part of the web standards. They first used it in the year 2000, but a couple of years later Mozilla, Safari and Opera were also implementing it.
The standards covered that topic a lot of time after it was already implemented in all major browsers, and AJAX was already in the wild.

One strong aspect of JavaScript that was pretty important and that, IMHO, made the adoption of the “AJAX paradigm” a lot easier, is that JavaScript was already compliant with the “event-driven” programming paradigm, and the use of the XMLHTTPRequest object didn’t add anything new to this paradigm.
Just as callbacks were added to respond to DOM Element’s events, callbacks were used to handle server side answers. Although AJAX changed the way web applications were created, it did that by mantaining the event-driven programming paradigm.

Oh, another thing happened to JavaScript in the last couple of years, Canvas.

Canvas is following the same trend the XMLHTTPRequest object followed. It has been adopted by most browsers (Opera, Gecko, Webkit) and despite Internet Explorer’s efforts to not adopt this new feature, libraries already exist to make Canvas compatible with IE (to a certain point).
A couple of nice libraries that used Canvas were released last year: John Resig published Processing JS. Some other libraries that make use of canvas were also released, one of them is the JavaScript InfoVis Toolkit (my library! :) ).
The number of Canvas related stories really grew at Ajaxian, and there were also new breakthroughs by Opera and Firefox on the implementation of Canvas 3D.

There is one caveat to this Canvas thing though, it doesn’t use extensively the event-driven paradigm. Since all these Canvas implementations are related to Cairo and also take things from OpenGL and Direct3D (this is notably the case for the Canvas’ 3D API), IMO these concepts are more related to a functional programming paradigm than anything else.
I mean, 2D/3D graphics are all about geometrical operations. And geometrical operations are mathematical functions. These concepts might be harder to grasp than the “”AJAX paradigm”", and that’s why the adoption curve won’t be as high as the AJAX one, but there’s no doubt that Canvas developers are a niche.

And do you know which objects/types/classes are related to geometrical computation, Canvas, Canvas 3D, Cairo, OpenGL and Direct3D?

  • 2D, 3D Vectors
  • Matrices
  • Intervals
  • Complex Numbers
  • Polar Coordinates

That’s exactly what I mean. The next logical step to bring a easier use for Canvas related programming should be operator overloading. This is the one feature that will be extensively used by JavaScript Canvas developers, since they have to deal with points, 2D and 3D coordinates all day.

For a last example, consider an interpolation function between two complex numbers

(to.$add(from.scale(-1))).$scale(delta).$add(from)

The same thing with operator overloading would be:

from + (to - from) * delta

You would make a developer’s life happier.