Monday, April 14, 2008

Missing Explanations

I was looking over my last post and forgot that I didn't discuss these two methods below:
Function.prototype.everyTimeButFirst=function() {
var self=this;
var toCall=function() {
toCall=self;
return null;
};
return function() {
return toCall.apply(this, arguments);
};
}

Array.prototype.toString=function() {
var result="[";
var addComma=function() { result = result + ", " };
var addCommaOnlyAfterFirst=addComma.everyTimeButFirst();
Array.prototype.each.call(this, function(every) {
addCommaOnlyAfterFirst();
result = result + every;
});
return result + "]";
}

It might seem a little overkill to have the everytimeButFirst function, but I think it reads better in the method and communicates the intent. Normally, you could implement putting in the comma in between items in the collection like so:

Array.prototype.toString=function() {
var result="[";
var shouldAddComma=false;
Array.prototype.each.call(this, function(every) {
if (shouldAddComma) {
result = result + ","
} else {
shouldAddComma=true;
}
result = result + every;
});
return result + "]";
}

It's a little bit longer. I hate the boolean variable "shouldAddComma". I really do. It just doesn't read well. It's hard to see what's going on. The naming makes it better. But, it's just adding unnecessary noise.

But, all is not well in the first version that I used either. Not all programmers are versed in functional programming, but even a functional programmer would scoff at the first version. Why? It changes state. Plus, the implementation of everytimeButFirst while clever would not be obvious. Basically, what you're seeing is my experiment in using nothing but functions instead of a boolean. Fun for blogging and brain stretching, but not for production systems. Clever is the enemy of the maintenance programmer. But, what if we did this:
Function.prototype.everyTimeButFirst=function() {
var shouldExecute=false;
return function() {
if (shouldExecute) {
return toCall.apply(this, arguments);
} else {
shouldExecute=true;
return null;
}
};
}

You might say I just displaced the boolean to somewhere lese and you would be right. But, I got it out of the method toString which is where I didn't like it. It's safely behind a wall where it makes sense to have. The internal implementation of everyTimeButFirst was too clever the first time around. It is still using higher-order functions, but one is easier to understand than nested ones that change themselves out.

Remember I said the original implementation would make a functional programmer gag because of the side-effects. We could make it side-effect free by making it recursive. But, Javascript is not optimized for tail-recursion. So, I did what I thought was best.

Sunday, April 13, 2008

"Super" was wrong

My implementation of "super" was wrong. I did an implementation in this blog post. It was wrong for several reasons. The number one reason was because it was too complex. The first hint that it was too complex was when I was setting the "constructor" property manually. This is done for you and only needs to change if you set the constructor's "prototype" property with "{}" or "new Object()". I was guilty of the this sin. Turns out if I play by the rules, I don't need the "subclassFrom" function nor do I need to add the special "super" properties. It's actually less verbose and it's playing by the Javascript rules. When in Rome, do as the Romans.

My second mistake was that I thought each object had an immutable property "prototype". This is why I was getting "undefined" when I asked for it. I should have known that I was wrong and not the implementation. Anyway, my belief was WAY WRONG. I don't know where I got this piece of mythology from. I think I pulled it from the sky. The truth is that the "prototype" property is only on Function objects. It's set on the objects it constructs and it is not available. Mozilla and Adobe implementations have a property "__proto__" that stores it, but it is not in the standard and thus, not to be used. All objects by the standard should get their prototype from their "constructor" property. Learn something new everyday.

For the new implementation, I got rid of the "subclassFrom". It's not needed now and I'm only left with the "methods" function from before. It now simply moves properties from one object to another. It's only for syntactic shorthand now. I did add something new: function "proto". It's "super" basically. Here's the implementation:

Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
this.prototype[each]=funcs[each];
}
}
Object.prototype.proto=function() {
return this.constructor.prototype;
}

So, how do you do super by playing by the rules? Here's how:
Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
this.prototype[each]=funcs[each];
}
}

function Base() {
print("base constructor called");
}
Base.prototype.toString=function() { return "aBase"; }

function Sub() {
this.proto().constructor.call(this);
print("sub constructor called");
}
Sub.prototype=new Base();
Sub.prototype.toString=function() { return this.proto().toString.call(this) + " and aSub"; }

Output from the above:
base constructor called
********
base constructor called
aBase
********
base constructor called
sub constructor called
aBase and aSub

Notice the "this.proto().constructor.call" in the Sub constructor function, it expands to "this.constructor.prototype.constructor.call". This is calling the "super" constructor. We could also do "arguments.callee.prototype.constructor.call" instead, but really it's a lot to type in isn't it? We also couldn't put that into a function as easily without calling "arguments.callee".

I got a better implementation and something that's more like Javascript. I like keeping my Javascript close to what a Javascript developer would expect. Prototype-based programming is powerful and it's worth exploring things without classes. But, that's a small digression. All I wanted was super and some shorthands for grouping my methods. I have that now.

Annotations and Aspects in Javascript

Here's the moment, I've been building up to:
var logAround=function(func,name) {
this[name]=defineAround(function(proceedFunc) {
print("before: "+name+" "+Array.prototype.slice.call(arguments,1));
var result=proceedFunc();
print("after: "+name+" "+result);
return result;
}, func);
}

var doesItLog=function(each) {
return each.log == true;
}

Transaction.prototype.eachFunction(logAround.onlyWhen(doesItLog));

var test=new Transaction();
test.begin();
test.commit();

Here's the output:
js> load("aspect.js")
before: begin []
begin
after: begin undefined
before: commit []
commit
after: commit undefined

Not much to explain at all. I think the code speaks for itself. The output shows the arguments passed in and what the results were from the call. I didn't return anything from either method, but it wouldn't be hard to verify that it does indeed work. I implemented my own "toString" for Arrays to print out the arguments and it's worth looking at. "arguments" is not an array, but we can call array functions on it. Most of the built-in Array functions can be called on any object. You just have to use the wordy "Array.prototype.functionName.call" to use it.

I wrote this for this blog post, but I'm planning on beefing it up with exception handling and un-weaving among other things. I also plan on adding more tests to my test suite that I did not show. The purpose was to show some cool tricks in Javascript and I hope it was fun.

And here's the entire implementation once more:
function defineBefore(beforeFunc, proceedFunc) {
return function() {
beforeFunc.apply(this,arguments);
return proceedFunc.apply(this, arguments);
};
}

function defineAfter(afterFunc, proceedFunc) {
return function() {
var result=proceedFunc.apply(this, arguments);
afterFunc.apply(this,arguments);
return result;
};
}

function defineAround(aroundFunc, proceedFunc) {
return function() {
var args=Array.prototype.slice.call(arguments,0);
args.unshift(proceedFunc.bindTo(this));
return aroundFunc.apply(this, args);
};
}

Function.prototype.bindTo=function(thisObject) {
var selfFunc=this;
return function() {
return selfFunc.apply(thisObject, arguments);
};
}

Function.prototype.everyTimeButFirst=function() {
var self=this;
var toCall=function() {
toCall=self;
return null;
};
return function() {
return toCall.apply(this, arguments);
};
}

Function.prototype.onlyWhen=function(ruleFunc) {
var self=this;
return function() {
if (ruleFunc.apply(this, arguments))
return self.apply(this, arguments);
}
}

Object.prototype.each=function(everyFunc) {
for (var name in this) if (this.hasOwnProperty(name)) {
everyFunc.call(this, this[name],name);
}
}

Object.prototype.eachFunction=function(everyFunc) {
this.each(everyFunc.onlyWhen(function(every) {
return every.constructor == Function;
}));
}

Object.prototype.run=function(func) {
func.call(this);
}

Object.prototype.define=function(name, annotations, func) {
this[name]=func;
annotations.each(function(each, name) {
func[name]=each;
});
}

Array.prototype.each=function(everyFunc) {
for (var index=0; index < this.length; index++)
everyFunc.call(this, this[index], index)
}

Array.prototype.toString=function() {
var result="[";
var addComma=function() { result = result + ", " };
addComma=addComma.everyTimeButFirst();
Array.prototype.each.call(this, function(every) {
addComma();
result = result + every;
});
return result + "]";
}

Annotations in Javascript

Last post, I talked about how to implement crude aspect advices. I say crude because the implementation would need to be beefed up a bit for wider use. The ideas were more important. I wanted to spend the article on the tricky bits of implementation. I'll take the same tactic with this article.

Let's start with what our code will look like. In fact, let's implement something everyone is familiar with: a transaction. Now, our transaction will have a blank implementation (we'll print out the important bits). It's the API that we will care about later. Here's the definition:
function Transaction() {
}
Transaction.prototype.run(function() {
this.define(
"begin",
{log: true},
function() {
print("begin");
});
this.define(
"commit",
{log: true},
function() {
print("commit");
});
this.define(
"rollback",
{log: true},
function() {
print("rollback");
});
this.toString=function() {
return "i am transaction";
}
});

OK. There's some new functions named "run" and "define". I'll show their implementations soon. You can probably guess the implementation of "run". It's simply so that my hands don't get tired typing "Transaction.prototype". I could use "with {}", but I have found its implementation inconsistent among Javascript dialects. The next new function, "define", is how we're going to define our annotations. It's a shorthand for better readability and to reduce duplication. All it will do is add the function to our object and add the annotations as properties. Annotations are simple in Javascript because functions are just objects and we can add anything we want to them. How cool.

Here's the implementations:
Object.prototype.run=function(func) {
func.call(this);
}

Object.prototype.define=function(name, annotations, func) {
this[name]=func;
annotations.each(function(each, name) {
func[name]=each;
});
}

Both are straightforward. But, I introduced another function: "each". Those familiar with Ruby will notice what it does right away. For the non-Rubyists, it iterates over all the properties of the object. My implementation also sends the name of the property as an extra parameter. Here's how I did "each":
Object.prototype.each=function(everyFunc) {
for (var name in this) if (this.hasOwnProperty(name)) {
everyFunc.call(this, this[name],name);
}
}

It basically allows me not to have a "for" loop. Simple. You might have noticed my use of "call". The reason is because I wanted to pass along "this" to the function passed in.

That is it for implementing annotations. The query language is already built in (albeit a little verbose). We only have to iterate over the functions of an object. Here's some code I would like to use to test my annotations and query implementation:

var every=function(each,name) {
print(name);
}
var doesItLog=function(each) {
return each.log == true;
}
Transaction.prototype.eachFunction(every.onlyWhen(doesItLog));

Oh boy. Can you guess the output from the above? Here it is:
begin
commit
rollback

The annotations I have is to mark a function to be logged on entry and exit. I'll spend the rest of the article on the implementation and bring together the annotations, aspects, and logging in the next article.

Let's talk about the new functions: "onlyWhen" and "eachFunction". I think you can guess what each of them do. "onlyWhen" is defined on a function and takes a function to check the arguments for some condition. If the condition is true, it executes the receiver function. It returns a function that brings all of this together. This is more functional programming at work. "eachFunction" takes a function that will be called for each function that is a value of a property on the object.

Like always, here's how I implemented them:
Function.prototype.onlyWhen=function(ruleFunc) {
var self=this;
return function() {
if (ruleFunc.apply(this, arguments))
return self.apply(this, arguments);
}
}

Object.prototype.eachFunction=function(everyFunc) {
this.each(everyFunc.onlyWhen(function(every) {
return every.constructor == Function;
}));
}

In the "onlyWhen" implementation, I have to bind "this" (the function) to self so that we can use it later in the function that we use a result. "this" will be bound to a different object. "eachFunction" brings together the functions "each" and "onlyWhen".

That's it! You could of course add implementations to define annotations so that we make sure that only pre-defined ones are used in functions. I'll leave that as an exercise to the reader. It wouldn't take much to implement it. The next article will put everything together. All we have to do now is weave based on rules. We have the means to iterate over functions and we have the means to replace implementations through our advices. The next article will mix this batter.

Friday, April 11, 2008

Aspects in Javascript

Just like I promised! I'm going to describe how to do aspects in Javascript. Now, this example will be simplified. You will probably want to beef up the implementation given here. I'm really showing off an idea and how you can apply it to your Javascript libraries. I did this for fun and was shocked how easy it was. In these examples, I will be using Spidermonkey.

I'm first going to show off how to implement advices. Let's start with "before" advice and then have a simple test for our implementation. I would recommend using JSUnit for testing. I'm simply going to output it for demonstration purposes.

The easiest advice to implement is "before". All we need to do is define a function that creates a new function that calls our before function and then calls the function we originally wanted to call. "defineBefore" handles this quite nicely. The rest of the code below is defining our "before" advice and the function we want to call and then doing the wrapping. Pretty simple.

function defineBefore(beforeFunc, proceedFunc) {
return function() {
beforeFunc.apply(this,arguments);
return proceedFunc.apply(this, arguments);
};
}

function printArg(x) {
print("proceed: " + x);
return x + 1;
}

before=function(x) {
print("before: " + x);
}
printArg=defineBefore(before, printArg);
print("result: "+printArg(6));

Here's the output:

js> load("aspect.js")
before: 6
proceed: 6
result: 7

You can see from the results that our "before" advice implementation can look at the arguments (but, not change them, we'll get to that). And be basically benign to the whole operation. Our weaving works!

"After" advice is equally as easy. We just need to remember the result and return that from our weaved function. Again, the "after" function will be benign and not be able to change the result. Here's the implementation:

function defineAfter(afterFunc, proceedFunc) {
return function() {
var result=proceedFunc.apply(this, arguments);
afterFunc.apply(this,arguments);
return result;
};
}

after=function(x) {
print("after: " + x);
}
printArg=defineAfter(after, printArg);
print("result: "+printArg(8));

Here's the results:

js> load("aspect.js")
before: 8
proceed: 8
after: 8
result: 9

Now, our "before" and "after" advice weaving did not allow us to change the arguments or results. I wanted to keep it simple without a lot of complications. If we need to change the arguments or tamper with the result, let's do it with an "around" advice.

The implementation for "around" is a little bit more complicated. I want to make calling the proceed function as simple as possible in the after advice function. To do this, I need to wrap the proceed function with another function that will bind the "this" so that we don't have to worry with sending "call" on the proceed function. The implementations before didn't have to deal with the proceed function in the advice and that made life easier. Now, we'll have that control and with that power, comes the ability to change arguments and results. Here's the implementation:

Function.prototype.bindTo=function(thisObject) {
var selfFunc=this;
return function() {
return selfFunc.apply(thisObject, arguments);
};
}

function defineAround(aroundFunc, proceedFunc) {
return function() {
var args=Array.prototype.slice.call(arguments,0);
args.unshift(proceedFunc.bindTo(this));
return aroundFunc.apply(this, args);
};
}

function concatAndPrint(first,second) {
print("first: "+first);
print("second: "+second);

var result=first + second;
print("concat result: "+ result);

return result;
}
around=function(proceedFunc, first, second) {
print("around first: "+first);
print("around second: "+second);
var result=proceedFunc(first, second);
return result + "c";
}
concatAndPrint=defineAround(around, concatAndPrint);

print("final result: "+concatAndPrint("a","b"));

And where would we be without the results?

js> load("aspect.js")
around first: a
around second: b
first: a
second: b
concat result: ab
final result: abc

One more detail, I didn't do an error handling or recovery. You will probably want to wrap any kind of exceptions that might happen in the proceed function and take appropriate action.

So far, our implementation is nice and clean. We're mainly using functional programming concepts for it. The next steps is writing the implementation for the pointcuts and combining that with what we did here. I'll also going to show how to define annotations. Trust me it's going to get more fun as we combine the batter and get ready to bake!

Tuesday, April 08, 2008

Javascript Inheritance with super

One thing that has always bothered me about Javascript is there is no implementation of "super". Most texts suggest to simply call the super function explicitly via its prototype. It makes for refactoring your inheritance hierarchy no fun because of the direct calls. And let's not mention all the duplication.

Let's think for a minute. Everything in Javascript is an object. What if we added the super automatically to the overriden functions so we could get access to it? And while we are at it, why not make our object definitions a bit more explicit along the way?

So, I whipped up the following code:

Function.prototype.subclassFrom=function(superClassFunc) {
if (superClassFunc == null) {
this.prototype={};
} else {
this.prototype=new superClassFunc();
this.prototype.constructor=this;
this.superConstructor=superClassFunc;
}

}
Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
var original=this.prototype[each];
funcs[each].superFunction=original;
this.prototype[each]=funcs[each];
}
}

It's two very short functions. But, it allows me to do this:

function Parent(z) {
this.z=z;
}
Parent.subclassFrom(null);
Parent.methods({
methodOne: function(x) {...},
methodTwo: function() {...}
});

function Child(z,y) {
arguments.callee.superConstructor.call(this,z);
this.y=y;
}
Child.subclassFrom(Parent);
Child.methods({
methodOne: function(x) {
arguments.callee.superFunction.call(this,x);
...
},
methodThree: function() {...}
});

"arguments.callee.superFunction.call" is a little verbose, but it's better than duplicating the name of my "super" implementation prototype all over the place. Plus, how often do you call "super". I generally think too many calls to "super" is a design smell.

I like this approach mostly. The only thing I don't like is the names I chose. But, I'll keep working on it. I was just happy in two functions, I have "super" in my constructors and functions. If anything, it's a different way of thinking about the problem.

Coming next, how to do aspects and annotations in Javascript.

Saturday, April 05, 2008

A Phrase Past Its Expiration Date

I've been a fan of Roger von Oech for a long time. I love his books, blogs, and cards (yes, cards). His latest blog entry entitled, "A Phrase Past Its Expiration Date", struck a chord with me that I thought I would share. In it, he asks his readers what phrases are overused and should be put to rest. His phrase was "It is what it is." The reason why was because it is commonly used to end debate and thought.

There are several phrases that carry the same role. Here's mine:

  • "YAGNI" also known as "You Ain't Gonna Need It"
    If I never heard this phrase again in my entire life, it would be too soon. I hate it. The original intention was well meant, but many a poor developer took it the wrong way. I've heard it uttered too many times to end discussion because a weak mind couldn't support their assertion.

  • "Do The Simplest Possible Thing That Could Work"
    Another well-intentioned phrase that originally came from Albert Einstein. How could it be bad? Again, I've heard it from one too many hacks to be lazy and not think through their design. It was once used in a debate to store records in XML files instead of a relational database. Even though it was known that the system was to deal with lots of records that had to be randomly accessed. Why? Because they thought relation databases were "hard". The resulting XML files architecture turned out to be way more complex than any OO mapping tool could dream of being. On the surface, the XML seemed simpler, but only when you ignored all the other factors to take into account. The above phrase ended the debate despite cries of the obvious. Confusion abounds because simple is often confused with easy instead of elegant.

  • "If It Ain't Broke, Don't Fix It"
    The maddening catch all to stop refactoring code that everyone fears. This one has been used because apparently certain developers like hearing the buzzing of pagers at 3am. The code in their eyes "worked" even though it was riddled with bugs. The code need to be cleaned, but they just wouldn't let it go. Fear is a terrible thing to use matras to justify.


That's my list for now. I'm sure there's more. I'm really bothered by most mantras because they are used in the most inappropriate places. I'm for debate and rational thought. Anything that short-circuits that annoys me without measure.

Friday, April 04, 2008

Monkey Patching

Monkey patching seems to be all the debate rage currently in the dynamic language blogosphere. The one that caught my attention was Gilad Bracha's in particular. I don't disagree with him at all. I know it's strange reading that from a Smalltalker. But, I view monkey patching like inheritance. It's a great device to have in your programmer back pocket, but can be dangerous. Use with caution and look at your options. Don't use it without thinking of the implications it can cause. The reason its dangerous is because it's a global change that widens the protocol of the affected object or worse changes the contract for an already existing method.

The main reason monkey patching is so dangerous is the global change it makes and the increased probability of having a collision if another project names a method the same. Or worse, another project overrides the default behavior and replaces it with their own. Both can cause subtle bugs that can be hard to catch and find. It's the global nature of it that can bite. It's convenient, but you should think twice before doing it. It's limits your project's options.

Groovy has a novel approach to monkey patching in that it allows them to be scoped for the duration of a block called categories. This reduces the risk of a global change and the addition is only in affect for the duration of the block. Now, it can cause issues if something gets called outside of the block by accident, which is why I wish it had different ways of scoping (class, package, etc). But, with AspectJ these problems can be reduced. Categories reduce a lot of the risk of monkey patching in that collisions are highly unlikely and the protocol is only widened for that invocation. It also ensures that unknown project dependencies will not creep in. I worry less about monkey patching in this instance because if you get burned, it will be your project not everyone else. I think categories are the way to go (if they added class scoped categories, I would be in heaven).

I don't hate monkey patching. Far from it. It is handy to override method implementations during debugging. I can change pre-existing methods if they have bugs in them even before the next release is out. I don't have to wait on the vendor. These are great pluses. I'm just advocating thought before you monkey patch in your own projects. Much like before you swing the inheritance hammer, you should do the same with monkey patches.

Tuesday, April 01, 2008

What's that Squeaking in Omaha?

If anyone in the Omaha area wants to learn how it's done in Squeak and Smalltalk, feel free to stop by at the Omaha Dynamic Language Users Group tonight. I will be speaking on what makes Smalltalk cool and how to setup your Squeak environment. Bring your curiosity and appetite. See you all there!