rolando.cl

You can have stupid ideas too

I have lots of ideas, and I like to discuss them with friends/colleges in order to test them before implementing them. This usually leads to ideas that are ok, ideas that are really good, ideas that suck and sometimes ideas that are plain stupid.

Assuming that you too can have stupid ideas is very important, because it can mean that you are thinking, and discussing your thoughts with someone else. This argument is good enough to make a stupid idea worthwhile.

I will also share some stupid ideas I’ve had with you:

When I was at the University, and we were learning Numerical Calculus, I came up with an awesome idea: poly-compress. You could compress a buch of data, just by defining the polynomial interpolation that would represent the data and then just “evaluate” the polynomial to reconstruct the original data. Sounds great! except that the data you need to create the polynomial is the same or more than the original information. Duh!

Today I was discussing a problem with a friend and I woke up with a great new idea, I rapidly emailed him with my proposed solution, only to find out after a few hours that it was the same thing that was already implemented, but with fewer comparisons: it was better, but marginally better. Duh!

I came to realize that the ideas were bad after discussing them with friends and trying to implement them. None of them was implemented of course, but just the exercise of thinking on how to implement them made me realize that they were pretty stupid ideas.

So… don’t be afraid to let everyone know that you can have stupid ideas too! You can even start a good discussion on why your idea is stupid and in that process you can come up with a good idea.

Lessons learned with Javascript

Some time ago I left my safe ruby & Objective-C lands to get into the bushy and wild javascript jungle. But surprise! it wasn’t that wild and there were some very mature and fun actors in here! Namely node.js and the V8 engine.

So, here are a few of the things I think I learned about javascript:

1 – Javascript is prototype1 based

Although some people may claim that javascript is an OOP2 language, I like to think that javascript is actually prototype based with lots of functional programming influence. Don’t get me wrong though, you can actually do some serious OOP with javascript (more on that later)

2 – Javascript can be fun!

Take for instance, jquery & jquery ui. Both of them are very well designed frameworks and actually very good programming practices.

3 – Namespaces

Although there are no actual namespaces, you can simulate them encapsulating functions/variables/objects inside other objects, for instance:

1
2
3
4
5
6
7
8
9
10
11
12
function foo() {
        console.log("global foo");
}

// empty object
var ns = {};
ns.foo = function () {
        console.log("foo inside ns");
}

foo();
ns.foo();

This takes into consideration that the definition is made under the “global” namespace, which would be window’s closure. One way to make sure this is the wanted behaviour is to be explicit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function (window) {
        function foo() {
                ...
        }

        var ns = {};
        ns.foo = function () {
                ...
        }

        // explicitly export symbols to the global namespace
        window['foo'] = foo;
        window['ns'] = ns;
})(window);

By creating the anonymous function (which receives as a single parameter the window object — you can pass other objects here if you want), you use your private closure inside: this way you do not contaminate the global namespace and only export the symbols you really want to export.

4 – Classes, Objects and being nice

In many places, you will see that the usual way to create a class is something like this:

1
2
3
4
5
6
7
8
9
10
// option 1
function MyClass() {
}

// option 2
var MyClass = function () {
}

// both options let you do this:
var obj = new MyClass();

What happens here is that the constructor is also the definition of the prototype for future objects, so things can get messy… In the end, looking at how frameworks like jquery & others do things, I opted for this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// empty definition
var MyClass = function () {};

var MyClass__prototype = {
        attribute1: "something",
        attribute2: null,
        
        // these are instance functions/methods
        foo: function () {
        },

        bar: function () {
        }
}

// these are class functions
MyClass.class_function1 = function () {
}

MyClass.class_function2 = function () {
}

MyClass.prototype = MyClass__prototype;

MyClass.create = function () {
        var o = new MyClass();
        // initialize o here
        ...
        return o;
}

// usage:
var someObject = MyClass.create();

This way, the constructor is clearly separated from the class definition, leaving no garbage in the object’s namespace.

5 – Add “static” typing through comments and check with closure compiler

Google’s closure compiler is a very handy tool that lets you “compile” your javascript code, but it also checks the code for common mistakes and also, if you comment your code The Right Way® then it also type-checks your code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        /**
         * @constructor {SomeClass}
         */
        var SomeClass = function() {};

        var SomeClass__prototype = {
                /**
                 * the position of the object
                 * @type {Object.<string,number>
                 */
                position: { 'x': 0, 'y': 0},

                /**
                 * this object's children
                 * @type {Array.<SomeClass>}
                 */
                children: [],

                /**
                 * adds a child - z and tag are optional
                 * 
                 * @param {SomeClass} child
                 * @param {number=} z
                 * @param {string=} tag
                 * @return {SomeClass}
                 */
                addChild: function (child, z, tag) {
                }
        };

Anyway… you get the idea. The whole thing is very inspired in jdoc and you should check the reference.

In order to compile the code, you can download the application (a .jar) and run it from the command line, or use the online application.

This is highly recommended for every javascript project since it will let you catch silly errors.

6 – Object properties are COW3 (at least on V8)

NOTE1 this is just an assumption of mine. Didn’t have the time to check it.

NOTE2 this is just something funny and not really relevant, but I find it very interesting.

When debugging my application I created a few simple objects just to see how they look under the debugger and also to learn a little bit more. So take for instance this simple example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var A = function () {};
var A__prototype = {
        prop1: "lala",
        prop2: "lolo"
}

A.prototype = A__prototype;
A.create = function () {
        // simplest constructor ever
        return new A();
}

// now test the code


var a = A.create();
console.log(a.prop1);
console.log(a.prop2);
a.prop1 = "something else";
console.log(a.prop1);
console.log(a.prop2);

If you place that simple example on an html page and load it in Chrome and check the debug console, you will see what you expect:

But if you set a breakpoint on the creation line, and trace through the code, something interesting appears:

As you can see, the object a is empty, but the prototype shows the properties as expected:

but… as soon as the property is written, it is “promoted” to the object’s closure:

Which I think is really cool :-)

UPDATE: This whole point is basically the result of javascript being prototype-based: an object holds reference to a common prototype, until it needs to be different, in this case, when the property changes specifically in the context of that particular object.

So what happens when you modify nested objects? take for instance the updated example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var A__prototype = {
        prop1: "lala",
        prop2: "lolo",
        prop3: {
                'x': 0,
                'y': 100
        }
}

var b1 = A.create();
var b2 = A.create();

console.log(b1.prop3);
console.log(b2.prop3);

b1.prop3.x = 500;

console.log(b1.prop3);
console.log(b2.prop3);

If you set a breakpoint right before the creation of b1, you will notice that when you modify b1.prop3.x, it is also modified in b2. This is obviously not the intended behaviour. One way to fix this is with accessors and setters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var A__prototype = {
        prop1: "lala",
        prop2: "lolo",
        prop3: {
                'x': 0,
                'y': 100
        },
        
        setProp3: function (x, y) {
                this.prop3 = {
                        'x': x,
                        'y': y
                }
        }
}

var b1 = A.create();
var b2 = A.create();

console.log(b1.prop3);
console.log(b2.prop3);

b1.setProp3(500, 100);

console.log(b1.prop3);
console.log(b2.prop3);

By doing it this way, prop3 is modified the way we wanted. This is actually very important and you might want to take that into account when creating complex objects and inserting them in the prototype.

Conclusions

I have to admit that coming from a language that is as beautiful and simple as ruby, I was a bit afraid of testing javascript, specially since most of what I remember of javascript is what I learned in the 90s. After giving another look at javascript and seeing that if you commit yourself to respect the good practices, javascript can be quite fun!

In the end, I hope that some of the lessons I learned from re-learning javascript might be useful to you.

1 http://en.wikipedia.org/wiki/Prototype-based_programming

2 http://en.wikipedia.org/wiki/Object-oriented_programming

3 http://en.wikipedia.org/wiki/Copy_on_write