Saturday, May 27, 2006

SmackBook

Way COOL!

http://www.youtube.com/watch?v=6uvQTTPr9Rw&www.reghardware.co.uk

Mixins, Interfaces, and Multiple Inheritance

As I've been doing Ruby programming for the last little while, I've discovered the concept of Mixins. Now, my programming experience in OO languages other than Java has been limited. I only did about a year of C++ at my first job before I ended up switching to Java, so that's why I haven't really been exposed to the notion of a Mixin before. But now that I've been using it a bit, I think it is in fact a rather wonderful concept! Interestingly, I've cooked up my own erzatz mixins in Java in the past without fully realizing what I was doing, but I think proper mixins really are more elegant!

A module in ruby is similar to a class with one major exception: It cannot be instantiated. You can execute methods on it statically, so for example you can have a Math module with functions like sin, consin, absolute_value, and so on. More interestingly, you can mix in a module into a proper Ruby class, whereupon all of the module's methods become available to the class as normal member methods - and the module's methods can in fact interact with methods supplied by the class. It is similar to multiple inheritance as implemented in C++ for example, but slightly weaker. C++ has full multiple inheritance, so it can do both interfaces as implemented in Java and mixins in Ruby as special cases. To make a C++ 'interface', you create a class with all pure virtual methods. To create a 'mixin module', you create a class with some pure virtual methods and at least one fully-implemented method which calls the pure virtual methods. However, in C++, you can do even more. You can simply write any number of fully functional classes, and then create another class which extends all of them. In OO, this means that wherever you have a reference to any of those base classes, you can substitute the subclass. Thus, every method from all base classes is valid for the subclass in terms of class invariants as well as preconditions and postconditions. Both Java and Ruby designers chose not to provide that degree of generality. I am guessing they felt encouraging developers to inherit from more than one fully-functional class is asking for trouble, especially as the inheritance chain becomes more than just one level deep! Mixins are a nice compromise: You can inherit functionality from a variety of sources (better than Java), but you can't arbitraily exend any number of actual classes with all the attendant headaches.

In Java, I have used delegation to do the same kind of thing that mixins provide, but without fully realizing what I was doing, until now! A while back I needed to write some code to find a loop in a network of oil facilities. Here is roughly what I did in order not to pollute the Facility class (loop finding after all is a lower-level behaviour) and to make the code easy to write test-first.
public abstract class Node {
public abstract List sendsTo();
public List findLoop() {
//recursively goes through the nodes in sendsTo.
//If it finds itself as it's going along, it returns
//a list of nodes that form the loop. Otherwise it
//returns an empty list. In my implementation, if
//there are multiple loops, only the first one
//this method finds it returned.
}
}
To get this to work with my Facility class, I implemented a class
FacilityNode as follows:
public class FacilityNode extends Node {
public FacilityNode(Facility facility) {
this.facility = facility;
}
public List sendsTo() {
//return a list of all dispositions of oil from this
//facility with non-zero volumes. Ignore dispositions
//of gas or water, and ignore oil dispositions that have
//0 volume.
}
}
Then in the Facility class, I use this FacilityNode as follows:
public class Facility {
//... whole bunch of other methods

public List findLoop() {
return new FacilityNode(this).findLoop();
}
}
This is admittedly far more awkward than simply mixing Node into the Facility class and implementing sendsTo, but it's the same general idea. One can see that the Node class can be expanded to include a variety of operations related to the topologies of networks and thereby provide far better overall cohesion in the application. In order to take advantage of these mixed-in methods, one need only implement a much small number of required methods, like sendsTo for example! Mixins are cool!

Tuesday, May 23, 2006

Mindless Ranting

When I talk about calling a function on an object, I use the word "method." I have no idea where it all started - probably those 4 gangtas started it. Those ghetto kids, always coming up with the crazy patois. What, plain english ain't good enough for 'em? Isn't it such a weird term though? Saying you're calling a function on a particular object seems clear enough. The term function has been around since the dawn of programming, so everyone knows what it means. Sure, it's not very OO, and someone - heaven forbid! - might think you're not all down with the objects. In that case, I am ok with "message." You send a message to a particular object. That's the smalltalk lingo, and it makes a certain amount of reasonable sense. It emphasizes the behaviour of objects over the idea of calling a function which manipulates data. Plus is has that OO cachet. When you talk about sending the hello_world message the person object, no one can look down on you as if you were some grubby C programmer, or worse, PHP! In a conversation with a coworker today, the only explanation I came up with was that if you were relying on polymorphism (whoa, I am not even going to get into that mouthful today!) to do the right thing, then the particular method of implementation of a given interface would depend on the subclass. So if you said the method of execution of a message on a particular object depends on the subclass, I wouldn't complain. It's long winded, but hey, it's ok. But if that's the idea, then what's "calling a method" all about? It just makes no sense to me! If that's the terminology you're going to use, well, just say "function." If you've made it this far, I'm impressed! :) Well, I don't know abou you, but I do feel better! And hey, if you're using "method" all over the place, don't feel too bad. When it comes down to it, so do I. As long as we're all drinking the coolaid together, it's all good.

Wednesday, May 17, 2006

What Is Good Code?

I've noticed that it's somewhat easier to deal with poorly written procedural code than poorly written object-oriented code. The reason, I think, is that the procedural code is all together in large unwieldy functions full of repeated conditional logic. One can take that kind of code and break it up into smaller functions, and then organize those functions into classes. Then one can take duplicate code and just call the appropriate methods instead. It's not necessarily easy, true, but it tends to be easier than cleaning up a confusing bunch of objects and factories. Often the code duplication in object code is hidden so it takes quite a while to figure out how the code currently works, and where the duplications starts and ends; rather surprisingly, it's also more difficult to figure out how to refactor the code to a better model. I think one potential reason that object code becomes problematic is that developers who are less experienced with OO tend to try to make their code "object-oriented." The approach I would recommend focuses on function rather than form. Consider paying attention to two qualities:
  1. Is your code easy to follow?
  2. Do you have to make changes in several different places when modifying or extending your code?
Focusing on these items, making the code clear and removing duplication, ought to naturally lead to nice clean object-oriented code.

Saturday, May 13, 2006

Developing Stories

Based on experiences on my current project, I felt I had something to say about how to write stories. A story should be short. A story should have a clear purpose that can be demo'd to a user on its own. If two aspects of the story can demo'd separately, then there is a good chance they should each be defined as a separate story. One should not throw in unrelated bits and pieces into a story - "Oh and while you're at it, do this here." I was spending some time thinking about how to clearly justify and explain these opinions of mine. Luckily, now I don't really have to: Brian Marick seems to have mostly done the job for me: http://www.exampler.com/writing/product-director.pdf

By the way, one idea that was introduced on my current project is excellent, and I'm not sure it's a standard agile practice. If not, it should be: The Demo. Each story should be demo'd briefly to the user when it has been completed. This practice insures that nothing significant is missing or misunderstood and tightens the feedback loop. The demo should be brief, no more than 5 or 10 minutes, and it should not include too many people - we had some problems with that in the beginning. Being able to demo a story to the user when it's been completed has proven to be both useful and simply satisfying for all concerned.

Don't Get Me Wrong...

I actually like Ruby, I really do. It's become my favourite language for programming at home. One major annoyance I ran into today though has to do with the way booleans are implemented. The number 0 is evaluated as true. So the following actually prints!

my_var = 0
if (my_var)
printf("my_var evaluated as true?!")
end

As long as you're in the world of pure Ruby, this is ok, since you should really be writing 'my_var = false' anyway so the if statement behaves. However, databases generally implement booleans as ints. In fact, if you declare a field as a boolean in mysql, it really just creates a tinyint in the background. When you set that field to false in Rails, it ends up being set to '0' in the database, and then when you evaluate it in a condition, it behaves very unexpectedly, even though in the code, it really is being set to 'true'. You have to use the '?' operator to resolve the problem, e.g.

if (my_active_record_object.flag_set?)
printf("This works as expected\n")
end

if (my_active_record_object.flag_set)
printf("This doesn't work as expected at all!\n")
end

It's a very insidious problem... This is one of those cases where I just kind of mentally shrug... WTF indeed!