Showing posts with label prototype. Show all posts
Showing posts with label prototype. Show all posts

Sunday, April 14, 2013

Why I'm using Coffeescript... For Now

To put it mildly, JavaScript has some idiosyncrasies. I've enjoyed manipulating, and exploiting some of JavaScript's more interesting aspects. However, it's uniqueness can cause confusion. It is perfectly fine to those with experience with JavaScript, but they often trip up even experience programmers that aren't well versed in the language.

Concerns about debugging

One major advantage of JavaScript development is how well debugging is integrated. Chrome and now Firefox debugging is pretty awesome. The only comparable interfaces I've used are Eclipse and XCode, and Chrome preforms better than either of these.
Initially I was concerned that the change in syntax and line numbers would make debugging difficult. Put simply, this turns out to this is much less of an issue than I anticipated. It is trivial to identify corresponding CoffeeScript code working backward from compiled JavaScript.

Class creation

It starts with simple class creation. In JavaScript there isn't anything to distinguish a Class from any other named function.
var MyClass = function(){};
That is, until you add methods to it.
MyClass.prototype.foo = function(){};
This is just weird.
CoffeeScript makes it a little more clear what is a class.
class MyClass   
    foo: ->

Which this is this

Here's a common scenario. I want to bind an instance method of an object to listen to an event (Mouse Click, AJAX response whatever). In java script I have to store this in a local variable so that I can use it later. Looks something like this.
var MyClass = function(){
    var t = this;
    $("a.bindo").click(function(){
        t.onClick();
    })
}

MyClass.prototype.onClick = function(){
    console.log("This is me", this);
}
I've used that pattern hundreds of time. It is useful, but again confusing to someone new to the language. The CoffeeScript version, by contrast, is succinct.
class MyClass   
    constructor: ->
        $("a.bindo").click @onClick

    onClick: => 
        console.log("This is me", @)
It is true that the developer has to understand on a conceptual level what is happening with the bind event, but I find that a simple character difference is more readily accessible and apparent than the JavaScript pattern.

Inheritance

CoffeeScript inheritance murders JavaScript inheritance. I have an older post on JavaScript prototype inheritance. It works (kinda), but again is unfamiliar to people coming from other languages.
CoffeeScript inheritance is easy, and offers something I've not seen cleanly executed in raw JavaScript. The super keyword in CoffeeScript called the super
in JavaScript to call the parent method it looks something like this.
var MyClass = function(){
    ParentClassName.call(this, arguments)
}
Now I think call and apply are super dope, but most of the time I would prefer to never touch them. Now the CoffeeScript equivalent
class MyClass extends ParentClassName
    constructor: ->
        super
That's is way easier, and way less likely to cause hard to track down bugs.

Integration with Ruby stack

In the 12 months we moved over to a Ruby stack after spending a long neolithic era using PHP. It is very easy to integrate CoffeeScript into an application using several Ruby frameworks including: Rails, Sinatra, and Serve. Not having to do any extra work to integrate CoffeeScript was a huge plus!

Dart

Dart looks awesome and I'll be following its progress, once it is supported by a couple major browsers (not just compiled to JavaScript), I'll be more than happy to give it a serious look. Strong typing and isolates are enough reason for serious consideration.

Conclusion

CoffeeScript isn't perfect. And I'm looking forward to new languages to come out for the browser platform. But the bottom line is productivity. And right now, for me and our team, CoffeeScript has a few key features that make web client dev less of a grind, while allowing us to leverage our JavaScript knowledge.

Sunday, March 25, 2012

What I learned from THREE.js: new way to encapsulate

Recently I've had the oportunity to work extensively with THREE.js, a WebGL framework primarily authored by Mr. Doob. This library simplifies the use of the powerful WebGL graphics engine. Not only is this library an excellent resource for WebGL, it also introduced me to some new techniques for JavaScript encapsulation and inheritance. This article presents a technique for simplifying method definition syntax.

Restructuring Class Implementation

The common method for adding methods to an object is to add the method names directly to the prototype.

var ClassName = function(){};
ClassName.prototype.methodName = function(){};

This works, but is a little verbose, and requires a lot of find/replace when overriding inherited methods. The clases in THREE.js avoid this repetition by defining instance methods during object construction. It looks like this.

var ClassName = function(){
        this.methodName = function(){};
};

The benefits are twofold. The syntax for method definition and overriding has been simplified. Also, Using the constructor for encapsulation obviates the use of closures to obfuscate private methods (as demonstrated in this previous post), further simplifying syntax.

Consider the following two classes.

/*
Class: ClassA
*/
var ClassA = function () {
        //add functions to object inside of constructor, simpler syntax
        this.foo = function () {
            console.log("parent foo");
            privateFoo.call(this);
        };
        //private methods also defined inside constructor
        function privateFoo() {
            console.log("parent private foo");
        }
    };

/*
Class: classB
inherits from classA.
*/
var ClassB = function () {
        this.foo = function () {
            console.log("child foo");
            ClassB.prototype.foo.call(this); //calling parent method
        };

        this.bar = function () {
            console.log("child bar");
        };
    };
ClassB.prototype = new ClassA();

var b = new ClassB();
b.bar(); //child bar
b.foo(); //child foo, parent foo, parent private foo

This is significantly more concise, and worth investigating further.

Issues

An obvious fault is that to call the parent method you have to access the child's prototype. This is conceptually confusing and a regression from the previously outlined method, where the parent prototype would be accessed (ie. ClassA.foo.call(this) ).

There is also a potential performance issue. It is possible that creating a new definition of instance methods at runtime will have an adverse affect on either memory footprint or speed. This will have to be tested.

Conclusion

It is to early to tell if I will start using this particular encapsulation scheme. The parent method mapping is a little strange, and the performance issue is something I'll have to investigate further. I will post any findings.

Saturday, January 28, 2012

JavaScript OOP - Protocols


Protocol are essential in life as well as programming. They define expected and required behaviors for different situations, allowing meaningful interaction to take place between unfamiliar entities. This allows common tasks to be completed in the face of new circumstances with minimal improvisation.

This post expands upon prototype inheritance, as outlined here, and demonstrates an implementation of protocols using Javascript objects. The common task in this case if the creation of a Mathematical series, and the protocol defines the series content

Protocol Base Class

This protocol (SeriesDataProvider) will have one required and one optional method. The required method (valueForIndex) generates the value of the member of a series for an index. it is require because an error will be thrown if it is not overridden in the inheriting class. The optional method (initFinished) is a callback that is called after the Series has been created.

/*/*
 * Protocol constructor
 */
var SeriesDataProvider = function(){};

//required method
SeriesDataProvider.prototype.valueForIndex = function(index){
     throw("this should be overridden by the inheriting class");
};

//optional method
//the passed series has finished initialization
SeriesDataProvider.prototype.initFinished = function(series){
     console.log("Series initialized", series);
};

*Series*

This next class uses a series data provider to generate its values. Looping from start to end indices asking the provider what the values are.

/*
/*
 * series implementation
 */
var Series = function(startIndex, endIndex, dataProvider){
     dataProvider.series = this;     

     //get servies values for indices in range
     for(var i=startIndex; i <= endIndex; i++){
          this.push(dataProvider.valueForIndex(i));
     }
     
     dataProvider.initFinished(this);
};
Series.prototype = new Array();

This first implementation overrides both inherited methods, and generates an arithmetic series.

var arith = new SeriesDataProvider();
arith.valueForIndex = function(i){
      return 1+i*3;
};
var arithSeries = new Series(0, 4, arith); //1, 4, 7, 10, 13

The next implementation overrides both inherited methods, creating a geometric series.

var geo = new SeriesDataProvider();
geo.valueForIndex = function(i){
      return 5+Math.pow(3,i);
};
var geoSeries = new Series(0, 4, geo); //6, 8, 14, 32, 86

This demonstrates how two similar, yet distinct, entities can be created with a minimal amount of new code. And while the example above illustrates a trivial case, the concept can be applied to more practical uses. One such case would be a protocol that works with a list of elements, providing elements for the list and determining behavior for different UI events.

EDIT:
Originally this post said that it was about delegates. That was not correct.

See Also:
Protocol in action.
Javascript Prototype inheritance