Sam Elsamman

Nerdy Musings and Other Stuff

A Type System with Benefits

I have been hard at work on a new type system for Javascript. Well actually it has grown into much more than that. I call it a type system with “benefits”. Those benefits are that it is fully typed so that object templates (similar to classes) have knowledge of the types of all properties which may include references to other objects. What does this buy you?  Actually quite a bit – all of which is demonstrated in the open source project Semotus. Here are the highlights:

  • The ability to serialize a complex graph of interrelated objects (code and data) and then restore them back to their original form with complexities such as:
    • Circular references
    • Polymorphic collections
  • The ability to use this to remotely synchronize objects between the browser and server. A node.js implementation shows how this can completely replace a function-oriented set of server calls with an OO approach to AJAX applications. Objects have Doppelgangers that remain automatically in sync between the browser and node.js and can call each other’s functions.
  • The ability to persist objects in a Javascript-oriented database (Mango/DB) and reconstitute them when they are read from the database with complexities such as:
    • Circular references
    • Polymorphic collections
    • Many-to-Many relationships

In this first of three articles I will discuss the fundamentals of the type system, called objectTemplate and in the next two I will introduce two derived type systems (remoteObjectTemplate for synchronizing objects between the browser and node.js) and (persistObjectTemplate for persisting objects using Mongo/DB).

Templates

A class is the fundamental template for creating objects in most OO languages but Javascript has no such concept. This is discussed at length in previous posts. Javascript may get classes at some point but given the glacial pace of adopting any new features in the language and having them be implemented by the popular browsers we simply cannot wait. To avoid any possible conflict with future language features we call our version of a class an Object Template. To be clear, however, this is a class in the spirit of classical inheritance and not the rough and tumble world of prototypal inheritance. It has to be that way if we are going to securely nail down client-server communication and automated persistence.

A template is a specification for an object that can be create by the new operator in Java Script. It defines properties and functions and assigns types to each property.

Animal = ObjectTemplate.create("Animal",
{
    name: {type: String},
    isMammal: {type: Boolean, value: true},
    legs: {type: Number, value: 2}
});

Lion = Animal.extend("Lion",
{
    init: function () {
        Animal.call(this);
        this.name = "Lion";
        this.legs = 4;
    },
    canRoar: function () {return true}
});

Bear = Animal.extend("Bear",
{
    init: function () {
        Animal.call(this);
        this.name = "Bear";
    },
    canHug: function () {return true}
});

Ark = ObjectTemplate.create("Ark",
{
    animals: {type: Array, of: Animal, value: []},
    board: function (animal) {
        animal.ark = this;
        this.animals.push(animal)
    }
});

ObjectTemplate is an object used to create object templates, in this case a base template Animal which is extended to provide details about Lions and Bears. Each property defined in the create or extend method will be created when an object is instantiated. The property may define data properties or function prototypes. For data properties an associative array defines the attributes of the property:

  • type – A Java Script built-in type such as String, Boolean, Number, Array, Object or an object template reference. Note that Object is for simple objects that simply associative arrays.
  • of – In the case of Array the type of each element in the array.
  • value – The initial value of the property when an object is instantiated

These are all the property attributes that objectTemplate cares about but derived type systems such as remoteObjectTemplate (remote objects) and persitObjectTemplate (persistent objects) have additional attributes.

Functions are simply defined inline. init is a special function that serves as a constructor and is invoked when an object is instantiated with new().

There is an additional mixin method on ObjectTemplate for adding properties after the template has been defined. It is needed in this example to define the ark property animal which can happen until after Ark is defined:

Animal.mixin({
    ark: {type: Ark}
});

So we are ready to board the animals:

var ark1 = new Ark();
ark1.board(new Lion());
ark1.board(new Bear());

Not that this object graph has circular references because the animals have a reference to the ark and the ark has a reference to the animals. Were we to try and serialize this object (covert it to JSON) with JSON.serialize we would just get an error “circular reference”. Even if we did not have the circular reference issue there would be no way to reconstitute the JSON back into functional objects with their embedded code again.

This is where objectTemplate provides real benefit. To serialize the object you just do:

var jsonArk = ark.toJSONString();

and to restore it back into a new object

var ark2 = Ark.fromJSON(jsonArk);

How is such magic achieved? To start with every object that is instantiated gets a unique identifier which is injected into the object as a property called __id__. This unique id allows us to replace all references to objects with the id of the object. This insures the object is only serialized once. The second part of the magic is that the serialization/deserialization has the benefit of knowing the type of object that needs to get instantiated for each object reference.

objectTemplate is suitable for both standalone use and as part of the Semotus framework.  I have used it to build a complex application with dozens of templates and complex references.  I could concentrate on just the logic and create a structure that made sense without having to worry about persisting it.  Later when I added the server component and persistence there was minimal rework get to a full stack application.

You can get objectTemplate here:

https://github.com/selsamman/semotus/blob/master/node_modules/semotus/objectTemplate.js

and see mocha test script with the examples above:

https://github.com/selsamman/semotus/blob/master/test/animals.js

One Response to “A Type System with Benefits”

  • Sam Elsamman says:

    Sure you can ask the consumers of your object to call an init method or specify extra parameters. This is just more details that the consumer of your object has to know about. Not a big deal if you are creating your own objects for your own consumption but becomes an extra layer of stuff that can go wrong when you are trying to create templates that are for wider consumption. ES 6 will support classes to formalize classical inheritance .

Leave a Reply to Sam Elsamman Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>