This list is my no means complete and as with the other list, I'll be appending to it here as I learn more.
Pimp My Library
I'll dive into some general theory about this first, but for those who just want to see the code, just scroll down.
There's been so many times when I've needed to add methods to classes, for good reasons. Well, I suppose I didn't "need" to, but the main good reason of course is readability. Having your data and operations on that data in one place is nice. Calling those operations consistently is very important.
Let's use an example in Scala. I couldn't find a "compact" method on List. It like seems it should be there. It's certainly useful. I could just create a method called compact, which takes a List, like so:
def compact[T]( list: List[T] ) = l.filter( _ != null )
But as I just said, calling operations on your data consistently is important for readability. Having this method forces me to call my operations differently. It's confusing calling some methods as infix, and some as prefix. Sometimes I say myList.whatever, and other times I say whatever(myList). The situation is even worse if that method takes arguments. myList.whatever(x), or whatever(myList, x). Inconsistent, confusing, ugly.
One solution is to simply add that method to the class you're operating on. Scala and Ruby both provide mechanisms for doing so, but they differ greatly. In Scala, I have to provide an implicit conversion from the class I'm operating on to a class that has a the method that I want to call. Here is the code:
class Compactable[T](l: List[T]){
def compact = l.filter( _ != null )
}
implicit def compactableList[T]( l: List[T] ) = new Compactable(l)
val list = List( 1, null, 2, null, 3, null )
println(list) // prints all values including the nulls
println(l.compact) // prints just the values 1, 2, and 3
This isn't terrible, but it really clouds my actual intent: I just want to add a compact method to List. Why should I have to convert it to something else, only to have the compiler figure out what I really wanted? While there are some other great uses for implicit conversions, in this particular case something that should be very simple has been made overly complex. Maybe there is a better way of doing this in Scala but I haven't seen it. In addition, I've seen this pattern so many times in Scala code written by other people, so I don't think there is a different way. This code is really just boilerplate.
In Ruby things are much more straight forward.
module Enumerable
def collect_with_index
idx = -1
collect{|elm| idx = idx + 1; yield(idx, elm)}
end
end
(Note: I've used a different method because the compact method already exists. I couldn't find a collect_with_index method.)
Here, I essentially just open up Enumerable and add the method to it. Done. The intent is preserved. Everything is clear, and simple. So simple in fact, that I don't even think I need to explain it.
I could imagine something very similar existing in Scala.
extend trait List[T]{
def compact = filter( _ != null )
}
This doesn't violate encapsulation because I'm not accessing any internals of List that aren't available to me otherwise. This could just be syntactic sugar for the Scala code above. Maybe someday.
Also, I think C# has similar mechanisms, but I'm admitting my inexperience. I'd love to see replies on how this is done in other languages.
Classes are Objects
In Scala, and Java, classes aren't really objects, at least the way they should be. Ruby (and I'm sure Smalltalk, and other languages) gets this right.
I had a discussion with my friend the other day and he asked, "what do you mean? I can call getClass on an object, and call methods on that class...". Eh, you can, but its still a weird fabrication. To a Rubyist, its laughable. So, without further ado, here's an example for Java programmers (in Java because Scala doesn't have static methods)
Let's say I have a simple little interface for a factory that creates Connection objects, and an implementation.
interface ConnectionFactory{
Connection createConnection( String user, String pass );
}
class ConnectionFactoryImpl implements ConnectionFactory{
Connection createConnection( String user, String pass ){
return new WhateverConnection( user, pass );
}
}
Then I have a client that uses a ConnectionFactory:
class ConnectionFactoryClient{
ConnectionFactory factory;
ConnectionFactoryClient( ConnectionFactory factory ){
this.factory = factory;
}
void doIt(){
Connection c = factory.createConnection( "dood", "secret" );
c.connect();
}
}
Now, imagine I had a class that had createConnection as a static method like so:
class ConnectionFactoryClass{
static Connection createConnection( String user, String pass ){
return new OtherConnection( user, pass )
}
}
You can see that the class itself seems like an object that implements the ConnectionFactory interface. If classes were really first class objects, and the class objects themselves could implement interfaces, then I could pass this class into the client like so:
new ConnectionFactoryClient( ConnectionFactoryClass )
You can do this easily in Ruby. This is because classes in Ruby are objects that respond to messages. They aren't really much different than the instances they create, just that the instances respond to a different set of messages the class.
I'm not advocating static methods here. This is something different entirely. Because the class is an object, and can be swapped out for a different object, you're not really statically bound to using that class the same way you would be in Java.
If classes could implement interfaces, you wouldn't have to go through the pain of creating a Factory instance, and passing that in, like this:
ConnectionFactory cf = new ConnectionFactoryImpl()
new ConnectionFactoryClient( cf )
Why go through the pain of creating a new class, and a new instance of a class, when you could use the class object itself. For the most part, classes are factories anyway.
Consider the following common pattern:
class MySQLConnection{
static public void createConnection( String user, String pass ){
new MySQLConnection( user, pass );
}
private MySQLConnection( String user, String pass ){ ... }
}
All the create logic is in one place, and the class is the factory. This, I think, is a good thing.
How could this be done you ask? To make this work with static typing, the language would have to have some construct that allows class objects to implement interfaces. It could look something like so (purpose any syntax you wish):
class MySQLConnection
(class implements ConnectionFactory)
(instances implement Connection){
static public void createConnection( String user, String pass ){
new MySQLConnection( user, pass );
}
private MySQLConnection( String user, String pass ){ ... }
}
We could probably take this even further to allow the constructors to serve as the implementations of the interface methods (maybe by giving constructors aliases).
One final note, in Scala, this would eliminate the need for the top level object that gets created when you define a case class. The class itself could be the object, and it would contain the apply method.
Anyway, that got long. I need to do something to structure this list a bit better.




