Monday, October 13, 2008

Why Reddit is Better than Stack Overflow (WAAAAY Better)

Ok, so to start, I am a recovering former addict of crackoverfl.... I mean stackoverflow.com. Honest! Look at my rank on the site (I go by "Mike Stone"). As I write this, I am 6th on the list of users sorted by reputation... and just a week or so ago I was holding steady at 3rd for quite a while. As you read this, I may not even be on that first page anymore.

There were times when I would be constantly looking for questions I could answer well... and other times I attempted to answer anything at all (that didn't go so well usually).

As a reformed addict, I think I can safely say a few things about the site. Whether they hold sway for you, or whether you agree or not... frankly I don't care much... because if you disagree, you are one of THEM....

So here it goes... Reddit has 1 thing going for it that I don't think Jeff Atwood will ever have... trust in the cloud.

That's it.

That's all there is to it.

The thing is, this is a touchy subject. In case you don't know what I'm talking about, I am alluding to the "close question" feature that Jeff so dogmatically believes is helping steer the users into asking the "right" questions. Instead, it is giving some users a power trip, because after all, they know what is good for the site. So they go ahead and close questions that clearly don't belong. Except some people find value in those questions, and it has a negative effect on the asker if they are powerless to disagree and change the decision.

If you are in the "we need to steer users towards our opinions" camp... I'll tell you right now that I hate you. Don't take it personally... what I really mean is I hate your stance, but it's more fun to just say I hate you. I don't like the power trip you feel, and I don't like that you are forcing your opinion down on my throat what should and should not be open for discussion. Yeah, the D word... I know Jeff doesn't like discussion on his precious baby of a site, but sometimes I want to go to the site for discussion. It's fun to answer answerable questions, and it's also fun to discuss interesting arguable questions with intelligent people (such as my most popular question). I want to do both, and I want to see both types of questions thrive.

But... Closing Questions is Working!

This is the argument I've seen from Jeff Atwood. He says closing questions is working, and he links to questions that have been closed as so-called proof. We have exchanged some emails, and when he sends me the links, I look at them. Every single time I've looked at his examples of questions that deserved to be closed, it is the same damn thing. The questions are either duplicates, have a negative vote total, have been deleted (likely because of offensive count), or they are gray area questions that more often than not I would rather see them on the site.

Duplicates Should be Closed, Right?

This is the single best reason for having the close question feature, except I think it is a problem best solved with a different, unimplemented feature. At least half the questions I see closed are marked as duplicates. Wouldn't it be neat if instead of closing duplicates, all the duplicates were congealed into 1 massive blob of a question? You go to one, and you see the blob... and all the questions are available, able to morph between the different forms via tabs (or some other mechanism). This way, the answers to all these similar questions can be viewed at once without having to scan for links to follow (and if you can't provide a link to the duplicate in question, don't close it as a duplicate... that angers me more than the close feature in general). The oldest one could even always be the first tab, so there is 1 canonical place to get the best answers, and all the others turn into alternative forms with possible nuggets of gold awaiting you to click its tab.

I have a secret about duplicate questions though... Jeff actually likes keeping duplicates around! If you don't believe me, here's a quote from an email he sent me:

There's no value in most closed questions, with the exception of edited duplicates which allow better search matching. People have the uncanny ability to ask the exact same question using totally different words, so we need these as breadcrumb trails.

So if duplicates are an important part of the ecosystem, and it's the only good use of closed questions (which I hope to show before you stop reading), then closing questions shouldn't be necessary at all.....

This One is Negatively Voted... Isn't That Proof Closed Questions ARE Working?

Not exactly. If it's negatively voted, this seems perfect proof that the voting system was a good system to implement. If a question is negatively voted, then people should be able to watch "hot" tabs and just not even see the negatively voted questions. There will be plenty of people watching all new questions who will vote it up if it was voted down inappropriately, and those same people will continue to vote it down if it really should stay down. Thus... why does it need to be closed?

If someone finds value in a negatively voted question, what is the harm in keeping it around? If the asker gets an answer he/she is happy with, who loses? If it is tagged appropriately, it probably won't even show up in the tag filters people set up (or the site automatically figures out) so that people who would rather not see it, won't see it.

So those questions don't REALLY need to be closed... voting dealt with them.

I Saw a REALLY Offensive Question Closed... That's Good Right?

These questions get marked offensive, and they get automatically deleted after 5 offensive marks. That is the purpose of the offensive feature, and it deals with those questions well... closing them is like closing a negatively voted question. Saying it is bad twice doesn't make it extra bad... just 1 way to say it is bad is all that is really needed (well, 1 way to say it's bad, and one to say it's REALLY bad... hense downvotes and offensive). I just laugh when I see a question that is negatively voted, marked offensive a couple times AND closed. I wonder if those people closing it think they actually did something valuable with their time....

What About The Rest?

So the rest are basically questions that are running dead even at 0 votes, or have positive votes. If this is the case... doesn't that mean someone is finding value in the question? This group is pretty varied. Some of them are polls on the best X, where X can range from programming comics to the best reference guide. Some people don't like polls, but I personally find them entertaining to participate in, and even sometimes find truly useful information.

You know who else likes polls on Stack Overflow? Joel Spolsky. That's right, the cofounder of the site talks about polls in his launch post, while Jeff grits his teeth when Joel mentions them on the podcast.

A lot of the other questions are discussions, which I've already mentioned I find value in. They help build the community, and provide outlets for your ideas or disagreements with your felow programmers.

Even more of the gray zones are borderline programming questions... usually they are somehow of interest to programmers, or IT people in general, so it seems to me they have a home there (or should, anyways). These range from Virtual Machine questions, to general troubleshooting problems with an OS or application that programmers will typically use. If they are tagged right, why can't they be on the site? If you are looking in your comfort zone of tags, you will never see the VirtualBox, or Ubuntu questions, so why can't someone get real use out of the site on such marginally programming related subjects?

So What Makes Reddit Better? I Heard it Sucks!

It seems a lot of people have lost faith in Reddit, and feel it has nothing left to offer. I find it quite the contrary... it is so addictive that I have to avoid it if I want to get any work done. The key to Reddit's success, I think, is the clever combination of subgroups and voting. The voting lets the interesting topics rise to the top. The subgroups keep those topics interesting for those looking at the group. That's why I always only go to programming.reddit.com, because every time I go there, I see really interesting articles about programming. It NEVER lets me down.

Stack Overflow could do the exact same thing with their implementation of tags and voting. Filter the interesting stuff to the top with voting, and keep it interesting to me with my focused set of tags. Think of each tag as a focused niche group where the stuff that rises with voting is going to be interesting to the members of that niche group. The only stuff that group of people would want to close are all stuck in other tags that don't even appear for them.

The next time you would close a question... reconsider leaving it open for someone in that niche group that would enjoy participating in the question.

So, that's the key, in my view. Reddit trusts the cloud and refines it with subgroups and it works. Jeff Atwood doesn't trust the cloud, and he turns people like me away who favor more open systems.

What of Proof?

Well, I'm not going to compile a long list of questions to prove my point... I've seen the proof with my eyes, and if I haven't convinced you that closing questions are unnecessary, I never will. I will, however, give you a short list of some questions I reopened because I felt strongly that they shouldn't have been closed. If you agree that any of these shouldn't have been closed, then maybe there are more that shouldn't have been closed.

The truly sad thing is that some questions that shouldn't be closed lose their chance at getting a good answer because someone was denied the ability to provide a good answer because of 1 selfish person that felt the need to push his/her opinion on everyone else.
The first was interesting to me because I actually want a low energy low cost linux box. Jeff Atwood has himself blogged about this on his programming blog, so it seems appropriate.

The second and third are VM questions... I use VMs daily for my programming work, so their effective use is of much interest to me (though I have not run into these particular issues).

The final one was something I wanted to thrive because the answers make for entertaining reads. Why can't we live with some humor now and then?

Final Thoughts

So, before I relinquish my control over you (as I apparently have some control, if you've gotten this far), I want to say a couple last minute things. I weened myself off Stack Overflow because I was sick of seeing questions closed that shouldn't be. I think it is a travesty to see people force their opinion of what to discuss on others. Though the number of closed questions may be small, it is unjust enough in my opinion that Stack Overflow is not worth my traffic, or my answers. Furthermore, it makes me depressed to see Jeff have so little faith in the system and community he built. Despite drastically reducing my usage, I reserve the right to ask questions when I have one I need answered... after all, I wouldn't be this impassioned if it weren't a good site!

If you don't like closed questions either, email Jeff Atwood (you can find his email on his blog if you look for it). Alternatively, open a uservoice ticket. The more people opening tickets the better... he might submit to pressure if he has to get rid of the tickets over and over. Just stick to 1 ticket though... unique users posting requests is a lot better than abuse of the uservoice system.

UPDATE:
cky brings up a great point in the comments that removing the close question feature will also do harm in causing other users to leave... a compromise between the 2 camps is probably the best solution. Some system of check/balance for the close question feature would be good, such as a simple majority vote. Other fair alternatives would be welcome in my book as well.

Sunday, October 12, 2008

Till Death do we Rewrite

It's been a while since it was written, but I recently read an interesting article from Joel Spolsky. It's from 2000, but it is of course still very relevant.

The article was about rewriting code, something he argues you should never do. It might be more fun and appealing to play devil's advocate, but I can't for this one. Joel is dead on here.

In my last job I was dealing with GUI code primarily. There were a few of us working on this section of the code, so it was by no means all my own work. One particular component of it was written by someone else who ended up moving on to another part of the project, so me and a few others inherited the work.

There came a time to expand on this component, and so I looked over what was done. It seemed somewhat awkwardly implemented, and I felt I could do a lot better if I started from scratch. There were events being raised and passed on 3 levels deep in the object hierarchy for no apparent reason, and the object structure itself seemed a bit awkward. It also got a bit slow under certain circumstances. Thus, I plowed ahead with a rewrite.

I started out strong. I had objects that correlated logically with what was being displayed on the screen. I had a simple structure that seemed a lot clearer and cleaner to me. It was working, and it seemed to even be faster. I was proud of what I had created (at least, at the time I was).

Then time went on and the GUI got more complicated. It sprouted the hairs that Joel talks of, and started getting slow for no apparent reason (but in different ways from the original implementation). All in all, the end result started looking a lot more like what had been there than I liked to admit.

The rewrite wasn't a total failure... it worked, and some of the details had definitely been improved, but at the cost of some new hairs that I would rather go back and fix. However, in retrospect, it would have been a much better idea to just dig in with the existing code and salvage what I could, refactoring what really needed improvement. I walked away with a valuable lesson though... whenever you want to rewrite code... don't. What is already there can work if you give it a chance. Refactor what doesn't work, and make the unclear sections more clear.

Learning to resist the urge to totally rewrite code is an important lesson I needed in order to become a better programmer.

Thursday, October 9, 2008

Please Hold on the Interfaces

I just got my first Notable Question badge over on stackoverflow.com for what seemed to turn into a rather controversial question. At the time, I was just ranting based on a question I had just read where all the answers suggested the use of an interface, when it didn't really seem to need one. Even more egregious, the interface was basically being proposed just to support testing.

To spare you a little reading, the basic premise of my question was: interfaces are overused, and it sucks when they are being overused, so what is it I'm missing, if anything?

This got some people to go NUTS over it! I mean, literally these people went wildly crazy, spouting nonsense... listen to this one, which was probably one of the worst responses I saw:

An issue with favouring mocking (or any kind of runtime substition) through subclassing, rather than through an interface, is that you can only override the behaviour of virtual members.

Invoking a virtual member requires an additional level of indirection via a Vtable and is slower than a final member. Whereas using an interface adds a compile-time overhead, but using virtual members adds a runtime overhead to every member invocation.

Surely, adding an interface **just to support mocking** is far preferable to slowing down your entire app **just to suport mocking**?

My preference, therefore, is to favour 'final by default'.



Talk about premature optimization!!!! This guy wants to avoid polymorphism because of the runtime costs?!?!? I can't believe how STUPID people can get sometimes! I mean, seriously! I try not to get angry when I'm on the Internet, because flame wars and trolling gets us nowhere, but c'mon now. A v-table call is going to be... what... nanoseconds? Even faster? So small we can't even reliably measure it??? And he thinks he has a net gain by avoiding that cost? I sure wouldn't want to be the one maintaining HIS code!

OK, I'm getting off topic. Interfaces. Those things that pretend to be a class, but have no details whatsoever. I don't mind them. Sometimes they can be quite helpful. However, like all tools, we must stop and analyze why we are going to use the tool, and what will we gain by doing it. If you pound on a screw with a hammer, you might just get it in there, but did you go about it the best way?

There are times when interfaces make a lot more sense in places they don't seem to belong, such as perhaps frameworks... though this guy rightfully pointed out that they also lock you in and restrict change, especially in frameworks (where you can't control who has implemented it).

So here's my biggest beef with interfaces: using one when you have a single implementation class.

That's it. That's the single most spine-curling, eye-gouging use of interfaces that will make me want to vomit all over you if you suggest it.

If you are a lover of interfaces, this may come as shocking news (as I sadly found out). Why is it so bad? You get to increase testability, right? You make your class more extensible, right? You are programming to an interface, right?

WRONG! No, no, no, no.... NO NO NO!

Testability

First of all, testability has nothing to do with whether you have an interface or not. It has to do with whether or not the dependencies you have in your class can be mocked out and altered so that you can ensure that the class works properly regardless of what those dependencies spew at you.

For example, let's say you have an object that represents a customer, which is represented in the database. Perhaps one of the worst things you can do is load the data for that object from the database from within the constructor. At this point, you can't get around constructing your object without depending on the database. Now, if you want to write a test for a DIFFERENT class that uses this customer object, you all of a sudden have to have the database up and running. This is bad because it makes the test a lot more complicated than it needs to be.

Now, if you are in the Interface Camp, you might be thinking... hah! If you define an interface for that class, you can get around that dependency! This is true, but it's also the easy way out. Singletons are also the easy way out to a lot of problems, but you don't hear many people clamoring for singletons everywhere, do you? The easy way out is oftentimes NOT the clean or best way out. Instead of shrouding your class in an evil interface, just move the database initialization to a protected method that the constructor calls. Now you can override the protected method in subclasses or mock classes and no longer depend on the database!

Extensibility...?

I just don't understand why people think classes are less extensible than interfaces. It just isn't true, damnit!! I've been extending classes left and right when I see the need, and I have never had a problem. The trick is, again, to avoid dependencies.

If you are doing something that can't be changed in a subclass, you might be doing something wrong. The constructor is the first place to look... is there behavior in there that does something that might be unwanted in an alternate version of this class? Is there a static initializer that is doing something fundamental to the class that can't be changed in a subclass? As long as you have only virtual methods (believe me, the "performance hit" is worth it... and it's why I love Java's default virtual and hate C#'s default final), and your constructors and static initializers are clean, you can reimplement the entire class as if it had been an interface all along! It's really not that hard, and if you are active with Test Driven Development, you will find the classes often come out that way anyways.

Programming to an INTERFACE....?!?!

Someone else said it better. I don't remember who, and I don't remember where. What do I look like, google? Find it for your own damn self! Well... the gist is, "programming to an interface" does not mean literally to a programming language construct called an interface... it means programming to a contract between you and users of your class... i.e. the publicly visible methods, fields and constructors agreed upon between you and clients of your class.

Just because "interface" is a keyword in some programming languages, doesn't mean we can't speak about "interface" as an English word used to describe what we are exposing.

Appropriate Uses??

I'm not going to lay out a bunch of rules on when you should use an interface. Deciding what tool to solve a particular problem is often somewhat of an art more than an algorithm, so you really have to look at the problem and just decide for yourself. You may end up using interfaces in an inappropriate time... but hey, we all make mistakes! Refactor it when you find a better way... you got all those tests to deal with it, right?

Without going into too much detail, I think a good rule of thumb for when to use an interface effectively is to use it when the thing you are trying to build doesn't lend itself to a default implementation, or you literally HAVE to do it... such as the case when you absolutely need to extend 2 classes (pick one, and extract an interface). However, there can be ways around needing the interface in these cases, but if the interface is cleaner, go for it.

You WILL Regret it Later!

No, you won't, but some claim you will, like this guy:

Sure, sometimes you may not ever have an alternate implementation of ISomeFoo in which case it might have been a waste for that particular component. But if you ever DO need to have an alternate implementation, going and changing those 50 references to concrete PetrolSomeFoo to concrete HydrogenSomeFoo will hurt really bad, especially if someone of the changes involve other applications or integration scenarios.

So, my argument is to let the IDE do the work for you. Extracting an interface and replacing all references is not all that hard of a task, especially given the help of a good IDE. If you are developing a framework where you don't control client code... this is one of the few cases where more interfaces might make sense, unless you have the balls to break backwards compatibility. If you have the ability to only use a tool when you need it, I say save on using that tool unless it really solves your immediate problem cleaner than other solutions.

Finish Already!

So the next time you reach for the interface keyword, stop and consider to yourself... is this really the best solution? Am I really solving this problem cleanly and elegantly with interfaces, or am I just hacking around a problem without considering how else I might solve it?

Monday, July 28, 2008

Why Java Generics Suck

When I first saw Java's Generics, I thought it was a pretty neat addition (rather harsh syntax, but effective). You get stronger type safety without all the extra casts. Less code with less room for mistakes, right? Well, yes and no. The problem is, Sun wanted to add this new feature, but at the same time preserve bytecode compatibility. There are probably a lot of reasons that maintaining bytecode compatibility is a good thing, but I just don't buy it.

So, what am I talking about you ask? Good question. The way Generics are implemented is via a thing called Type Erasure. What this essentially means is that the type information is there only for the compiler. So, if you have a List<String>, you don't ACTUALLY have a list of strings. You have a List that will only let you store and retrieve strings, but ONLY as long as you know the type of that list. I will get to an example in a little bit. My best guess at why Sun did this is they wanted to add this neat feature that C# had and C++ had, but at the same time they didn't want to cause upgrade problems where clients of your code MUST be using the Java 1.5 runtime. Except, if you use any of the new API, your clients are going to have to upgrade to Java 1.5 anyways, so it seems like a myth that they are ACTUALLY benefiting anyone by being backwards compatible. By trying to appease 2 crowds (those wanting more features and those wanting to be able to run on old runtimes), they ended up creating a bit of a Frankenstein's Monster in the process.

So if that garbled mess of a paragraph didn't help you understand the problem (which it probably didn't... I was really just ranting), then hopefully a concrete example will help.

Have you ever seen the warning "Type safety: The cast from Object to List is actually checking against the erased type List" or something like it? You can get it from the following code:

public static void storeInt(Object object, int value) {
List<Integer> list = (List<Integer>) object;
list.add(value);
}

What this means is that you tried to take an object without Generic type information (Object for example), and you tried to extract the Generic type information from it (Integer)... except that information was erased the moment you stored your list into a reference of type Object. Why? Because in order to preserve backwards compatibility, the generic type of Integer is not ACTUALLY available at runtime. This means you can end up recasting your list to the wrong generic type, and add elements of the wrong type, which can later cause a ClassCastException. Consider the following code:

public static void storeString(Object object, String value) {
List<String> list = (List<String>) object;
list.add(value);
}

public static void storeInt(Object object, int value) {
List<Integer> list = (List<Integer>) object;
list.add(value);
}

public static void printList(Object object) {
List<?> list = (List<?>) object;
for (Object value : list) {
System.out.println(value);
}
}

public static void main(String[] args) {
List<String> list = new ArrayList<String>();
storeString(list, "Hello World");
storeInt(list, 1);
printList(list);
}

The above code will not only compile, it will also print 2 lines, the first saying "Hello World" the second saying "1"... even though we have clearly violated our initial list of strings and stored an integer in there. However, let's add some more code. After the printList call in the main method, try:

for (String value : list) {
System.out.println(value);
}

Now you will finally see the runtime error you might have been expecting in the previous example. This time you will see "Hello World" followed by "1" followed by "Hello World" followed by a ClassCastException. This is because Java is trying to take the "1" and put it in the String value reference... but it's not a String, so we have a casting problem! If sun had implemented Generics right (which probably would have meant byte code incompatibility with 1.4), then the first time you tried to cast that list of strings as a list of integers, you would have gotten a ClassCastException. Furthermore you would have been able to do things like this:

public static <T> T createAndStore(List<T> list) {
T value = new T();
list.add(value);
return value;
}

and this:

public static <T> T[] toArray(List<T> list) {
T[] array = new T[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}

But with type erasure those 2 examples are impossible, because the type is unknown at runtime.

You may think that I am just ranting about these and that the issues never come up, but I assure you they do come up. If you are working with any legacy code or APIs that were not built when Generics were around and did not upgrade to use Generics (or were built when they were around, but the author(s) didn't think to use them)... or if Generics just can't solve the problem that a simple list of Objects can, then there can be issues.

Case in point: servlets. Take a look at the servlet API, particularly HttpSession's getAttribute method. I can only store and retrieve Objects, which makes sense. I should be able to store anything I want in the Session. However, the moment I store an object with Generic type in there... especially one that needs to be modified, I have thrown type safety out the window.

Let's say I store a list of strings in the session, and I want to add a string to that list periodically throughout my user's session. This doesn't seem so far fetched, right? Well, now how do you suppose to add items to that list once you have removed the String generic type information?

public static void addString(Object object, String value) {
List<String> list = (List<String>) object;
list.add(value);
}

causes a warning at the casting time like we discussed before.

public static void addString(Object object, String value) {
List list = (List) object;
list.add(value);
}

also causes a warning, this time at the point where we call add... because Java thinks we should be using Generics... after all, they spent so much time designing the system, you should always use it!

public static void addString(Object object, String value) {
List<?> list = (List<?>) object;
list.add(value);
}

causes an actual compiler error on the add call... because Java can't give you any guarantees that you are safely calling add with the correct type, so they just don't let you.

The solution? Well, you have to just use the SuppressWarnings annotation on the method where you want to add that string! Seems like a hack to me, but maybe you can live with that. Personally, I would rather just ditch Java and go use Ruby. None of this is even remotely an issue when you go dynamic.

Monday, July 7, 2008

C# Regions and Style

Often, Jeff Atwood has insightful and interesting things to say. I very often agree with his viewpoint, though every now and then it just doesn't quite sit well. That's probably important, to be sure that I am reading with a critical eye and not just taking his word on blind faith. The reason I start with this is his most recent post just didn't sit well with me.

I worked with C# at my last job. It had its perks and its problems, and it was a Microsoft product, which adds instant negative baggage (sorry Jeff, despite enjoying your writing and podcast material, I don't think I will ever understand your appreciation of Microsoft products). One thing I did like was #regions. C# is about as verbose as Java (at least it was before 3.0, which I never got to use but have heard they improved things a bit). As such, this often leads to large code files, especially in GUI code that has tons of event handlers and special setup code. I found at my last job that a small sprinkling of regions helped organize my code quite well. I could keep all methods of a particular type grouped together with the ability to toggle the code at will. Some of my favorite groupings were "Event handling", "Constructors" and "Utility methods". It just seemed cleaner to keep things together that are semantically similar. Though I prefer Java and (even more so) Ruby, Regions is one thing I wished I could take from the Microsoft world into the rest of the world.

He is completely right that it can be abused, though. I saw plenty of other code in the project that would simply have regions around every method definition, which just seemed redundant to me. I know Eclipse will allow this kind of code folding automatically, and I could swear Visual Studio did it also (but it has been long enough that I could just be thinking of Eclipse). At that point, the regions aren't grouping semantically similar concepts, and it ends up being quite a mess visually and organizationally. At least to me... I'm sure the author preferred it that way.

This leads me to conclude that the first part of his article is dead on. Despite my disagreement with the details of regions, I fully agree that a team must be aligned on code style. There is one class I missed in college that in retrospect I truly regret not taking. It was a class that everyone feared as being too hard, but everybody who took it ended up loving the professor. It was some kind of individual software project course, and the class was known for the professor enforcing a standard coding style on the students, with some rules purposefully contrary to common style guides. Thus, the student walks away learning the ability of bending one's will for the good of the team. Style is often a "religious" debate that has no answer. Both sides are valid, because it's just a matter of personal style. The style I consider beautiful is ugly to the next person, and likewise his or her style is ghastly to me.

The style I appreciate most of all though, is consistent style. If that means bending my style a little sometimes, then so be it.

Monday, June 30, 2008

Singleton Methods

Ruby has a neat feature called Singleton Methods. The idea behind them is that you can define a method on an instance of an object, and that method only exists for that instance. Sounds pretty crazy the first time you learn about it, but it can prove quite powerful. This feature only makes sense in conjunction with duck typing (which I would like to dedicate another post about at some point). Don't expect a JSR for Singleton Methods for Java any time soon! Actually, you can do something similar using an anonymous class, but it would be rather hard to invoke, and you would have to define the method at the point of creation.

How could Singleton Methods possibly be useful? Well, my personal favorite is for unit tests. I prefer testing with actual classes, but sometimes that is not feasible. The object in question may not be built yet. It may be a legacy object that you don't want to touch because there aren't all that many tests for it, and it would just be easier to pretend that you have an instance of it. Perhaps the most likely scenario is that you are using a framework, and it is just plain annoying or infeasible to construct the real version of the object in question. Sockets are a prime candidate for this exact situation. Whatever the reason, you want to mock an object. What do you do in Java? You either construct an anonymous class, or you define a mock class which extends the object in question (or implements the required interface), and voila!

Except... anonymous classes are rather cumbersome, and an actual mock class separates your mock logic with the test that requires it. You could of course have a general purpose mock that is used everywhere, but you will have to go back and forth between the mock definition and your test class definition whenever you are developing tests that use the mock.

In comes Singleton Methods to the rescue! Your method only connects, and then does some extra work once it is connected, so you just need to mock the connect method. The following code would accomplish this goal:

mock = Object.new
def mock.connect()
end
invoke_my_method_with mock
# assert some conditions

Then, you should have a test in case the connect fails, right? Your object needs to do some other logic when the connection doesn't actually connect! So, the next test mocks the object differently:

mock = Object.new
def mock.connect()
raise "Some exception"
end
invoke_my_method_with mock
# assert some other conditions

Because of duck typing, your method doesn't know that it didn't get an actual Socket, but you were able to keep the mock logic near the test logic (in a clean and concise manner), which makes it a lot clearer what the test is testing.

Making mocking easier is nice, but ever since I learned Singleton Methods, I have been itching to use it in another way. Let's say we have an entity in our system that has a set of actions possible. My favorite case is a character in a game. There are many possible actions, but our character is only able to use a few of these actions. He can kick, but he can't punch. Each command could be a different Singleton Method! Now, whenever the character wants to punch, just invoke punch with the actual character instance. Of course, this means you have to be prepared that the character can't ACTUALLY punch, so you must catch a method missing error and inform the character that it tried to do an action it didn't know how to do (or perhaps didn't even exist). I don't know how this type of design would actually pan out, but it sure seems like the perfect fit for the feature.

I bet there are other good uses for Singleton Methods, so don't let these ideas limit the possibilities!

Thursday, June 26, 2008

Thoughts on Groovy

So I have been working with Groovy for the last few weeks on a for fun project at home. Nothing special, just a game... one that will probably never see the light of day, but I will nonetheless have fun with it for a while. I am a bit disappointed with Groovy, probably because I came at it having first learned Ruby. Groovy is very heavily influenced from Ruby, but not quite enough in my opinion.

Before I get into some issues I have with it, I guess I should note that it isn't ALL bad. Namely, they did a great job of making (mostly) seamless Java and Groovy integration possible... in BOTH directions. This is the 1 thing I wish JRuby would borrow from Groovy. What is the problem you ask? Well, with Groovy, you compile down to classes, and the resulting class is more or less exactly how you would expect it to work. That is, you can construct the object from Java directly, then call methods directly on it, exactly as you defined in your Groovy code. If you specified types, you will have access to those type declarations from Java. This is really good if you have an existing code base you want to integrate with. If you are starting an application from scratch with no dependencies, well, you might as well just stick with JRuby or Ruby (or whatever inferior language you like), since you can control whether integrating with your language from the Java end is a big deal. I played a TINY bit with Rhino, and they seem to have a similar type if integration possible, but Groovy seemed a lot cleaner... with Rhino you have to compile the class to a given object or interface... so the code itself doesn't really have a definition of the type in this case. Seemed like a bit of a hack to me, but if you are primarily using it from the JavaScript side, it is really a non-issue. Oh, and I decompiled the results of all 3 of these languages (Rhino, JRuby and Groovy), and Groovy seemed to add the lease baggage in the code, but it still had baggage.

Also... if you are a big fan of static typing, then Groovy will be a good transition to dynamic typing because you can fall back on static typing whenever you want. Personally, I see no reason to, but I am one who loves dynamic typing.

Now some bad things. Perhaps as a direct consequence of the apparent design goal to integrate seamlessly in both directions with Java, the language feels very... inconsistent. They TRY to do things in a nice dynamic way, but then fall short in some cases that I think Ruby shines in. This leading to my biggest gripe... the distinction between fields and methods. If you are going to support fields of varying scope, you essentially can't have the kind of clean design you have in Ruby. What do I mean by this? Well, let's look at an example.

In Ruby, if you have a property named "property" then you would define it as such:

attr_accessor :property

Which is equivalent to:

def property()
@property
end

def property=(value)
@property = value
end

So what is going on here? Well... we still have the distinction of fields and methods, but in Ruby, your fields are ALWAYS private. You can't make them public, so when you call a method, it will never be ambiguous with accessing a field. This means, invoking a method with no arguments, you can just drop the parenthesis because they are redundant. In fact, you can even drop them when there ARE arguments, as long as it doesn't make it ambiguous in conjunction with other method calls or whatever. I think this makes Ruby as clean as it is, and makes it really look like you are reading English... almost.

What about Groovy though? Well, they support a similar paradigm. Defining the same property is 1 line as well, but it looks like this:

def property

And it is essentially equivalent to creating getProperty() and setProperty(value). BUT! The consequence of seamless integration with Java means you can't drop the parenthesis in every method case. They too support dropping them when there are arguments, and it doesn't make it ambiguous, except when there are no arguments and it isn't a getter. Thus, in Ruby you could have "stream.close" but in Groovy it would have to be "stream.close()". This may seem minor, but every time I have to add those parens in Groovy, I'm reminded that Ruby's grammar feels so much more internally consistent.

I guess I wrote a lot about that, but for some reason that minor detail really irks me. Before I just end with only a single gripe, I better add a couple more for good measure. I haven't tried nested classes in Ruby yet (though I've read they are possible), but Groovy definitely doesn't support them, at least not now. I think this is something they will eventually get to, but as it stands, this is a major limitation. This seriously cuts short the "seamless integration" with Java that I feel is one of the significant strengths of Groovy. Not much more I can say about that, but maybe it's also because it is getting late and I am tired.

One more issue? Null. Groovy tried so hard to be like Ruby, but they missed yet another thing that I really like about Ruby. In Ruby, nil (Java and Groovy's null) is an object, just like any other object. What does this mean? Well, null pointer exceptions... no such thing. Instead they become a method missing error. This was a very cool concept to me the first time I saw it. I'm not sure if it allows significantly more concise code, but it does seem to pretty up the code, at least to me. A list of method calls as conditionals is a lot easier for me to parse than a mix of == and method conditionals. Visually, calling methods makes each condition a single entity, unlike with an == or != conditional. For example:

if connection != null && !connection.is_connected

vs

if !connection.nil? && !connection.connected?

Which brings me to another point that I won't go into too much details... but being able to add question marks and exclamation points to my method names has got me wishing I could do it in every language. Beyond cutting a couple characters from the method length, they allow you to add meta info about the method that is visible at a glance... such as question mark for asking a boolean question, and exclamation for indicating state will be changed (which are essentially the Ruby standards for their usage).

Ok, I have ranted enough. I haven't proofread this, because it is late. If anyone happens to read this, just enjoy or hate it as it is.

Mike

Monday, June 23, 2008

A JRuby Swing Library

Well, I haven't really posted anything yet, mostly because there is always something else to do. So, in an effort to actually start writing something, I have decided to post a little Ruby "library" I wrote a while ago. I put in the sarcastic quotes because it's quite a tiny library, if you can even call it that, but I think it has potential to be quite useful. I recently ported it to groovy for another personal project, and maybe I will post that next.

At any rate, before I list the code, I just wanted to say what its purpose is. Call me crazy (I probably am), but I like Java's Swing. Why? Well, it's portable in the sense that Java is portable... that is, you can easily install Java anwhere and thus have Swing at your fingertips... you can't really say that for most other UI libraries I have used (admittedly a small list). Either your window library of choice is X platform only (I'm looking at you Microsoft), or is just not nearly as pervasive as Java. Swing also does an OK job of looking decent, in my non-graphical-arts-critical eye (so take that with a grain of salt), and it can mostly look like your native platform with a special toggling (somewhere buried in the API that I end up always looking up, even though it is 1 or 2 lines of code).

So, with the good comes bad. I'm sure you can site many other bad things that I just don't have the experience or interest to point out, but the leading problem I am aware of, both in experience writing Swing GUIs and in reading other people mention the problem, is that it is an inherently tree structure being expressed in a non-tree syntax. The solution? XML! Well, there are many other options besides XML that provide a tree structure and don't make you want to gouge your eyes out, but XML happens to be pretty easy to parse in that most languages have a pre-packaged XML library. Thus, XML! Besides, XML is a lowest common denominator, everyone basically understands it, right? Isn't that what the XML enthusiasts try to shove down our throats?

Thus SwingXML was born, my tiny "library" that will take an XML definition, and load it into memory as a Swing component tree. Beyond representing the components in their inherent tree structure, it has the added benefit of separating your view definition from your view logic. In the groovy version I added a feature that I have not yet added to the Ruby version.

Without further ado:

require "java"
require "rexml/document"

class SwingXml
def initialize(xml)
document = REXML::Document.new(xml)
@widget_hash = {}
@widget = handle document.root, nil
end

attr_reader :widget

def [](widget_symbol)
@widget_hash[widget_symbol.to_sym]
end

private
def handle(element, parent)
raise ArgumentError, "Element #{element.name} does not have an sxmlId!" unless element.attributes.has_key? "sxmlId"
raise ArgumentError, "Duplicate key found on #{element.name} (#{element.attributes['sxmlId']})!" if @widget_hash.has_key? element.attributes["sxmlId"].to_sym

widget = eval "#{element.name}.new"
@widget_hash[element.attributes["sxmlId"].to_sym] = widget

element.attributes.each do |name, value|
eval "widget.set_#{name} #{value}" unless name.index("sxml") == 0
end

element.elements.each do |child|
handle child, widget
end

if element.attributes.has_key? "sxmlAction"
eval "parent.#{element.attributes['sxmlAction']} widget" unless parent.nil?
else
parent.add widget unless parent.nil?
end

widget
end
end

So, that's it! Pretty small for doing seemingly quite a bit, right? If you are wondering how to use the above "library", think of the SwingXml object as the root of your Swing component tree, while it is also a hash of the contained components. Typically, you would have a JFrame at the root, but you could even break them up more fine grained and have them be a panel or canvas of some sort. The components contained within the tree are accessible via their sxmlId values as indexes, which are an attribute you must specify on each xml element. You can even add more complicated things like layouts and whatnot with an sxmlAction which specifies how the object should be added to its parent.

As a simple example:

frame = SwingXml.new "<javax.swing.JFrame sxmlId=\"frame\" default_close_operation=\"javax.swing.JFrame::EXIT_ON_CLOSE\"><java.awt.FlowLayout sxmlId=\"frameLayout\" sxmlAction=\"set_layout\"/><javax.swing.JButton sxmlId=\"helloButton\" text=\"'Hello World!'\"/><javax.swing.JButton sxmlId=\"goodbyeButton\" text=\"'Goodby World!'\"/></javax.swing.JFrame>"

listener = java.awt.event.ActionListener.new
def listener.actionPerformed(e)
puts "Hello world!"
end
frame[:helloButton].add_action_listener listener

listener = java.awt.event.ActionListener.new
def listener.actionPerformed(e)
puts "Goodbye world!"
end
frame[:goodbyeButton].add_action_listener listener

frame[:frame].pack
frame[:frame].set_visible true

For easier reading, here is the XML but not embedded in the Ruby code:

<javax.swing.JFrame sxmlId=\"frame\" default_close_operation=\"javax.swing.JFrame::EXIT_ON_CLOSE\">
<java.awt.FlowLayout sxmlId=\"frameLayout\" sxmlAction=\"set_layout\"/>
<javax.swing.JButton sxmlId=\"helloButton\" text=\"'Hello World!'\"/>
<javax.swing.JButton sxmlId=\"goodbyeButton\" text=\"'Goodby World!'\"/>
</javax.swing.JFrame>

In the groovy port, I added some code to remove the need for javax.swing.JXXX and java.awt.XXX, but I didn't add this enhancement to the Ruby code, but it should be pretty trivial to add. That small addition makes the XML a lot less of a pain to deal with. Well... less of a pain anyways.

I hope you enjoyed this, and I hope to make these posts more frequent!

Mike

Friday, March 7, 2008

Introduction

Hello everyone! I have been thinking about creating a blog for a long time, and I finally have. I have a lot I want to talk about, but for today I want to just start with who I am, and why I decided to start blogging.

So for starters, my title and blog name. I wanted my blog name to be ducktyping, after one of my favorite features of my new favorite programming language, Ruby, but alas someone beat me to it. The next best thing was an offbeat quote from Fry from my absolute favorite TV show, Futurama. It is from "Roswell That Ends Well" and is from a scene where fry puts a stove-top popcorn package in the microwave, it begins to emanate a blue glow, and Fry sniffs the air and says "Hey, what smells like blue?"

In case you are wondering who I am, well, my name is Mike Stone. I am a programmer, and my interest in computers and programming goes back to when I picked up a book on basic somewhere around the fourth grade. It has been my passion ever since, and I often spend free time reading about programming, thinking about programming, or actually programming. I graduated from Cal Poly San Luis Obispo in 2004 with a BS degree in Computer Science and have been working in the field primarily in C# since then. The first programming language I grew to really love was Java, though I initially approached it freshman year with doubts, seeing it more as a toy language. My classes proved me wrong, and I grew to appreciate what Java offered... a multi-platform managed programming language that made certain types of bugs impossible. I especially enjoyed the documentation, which I have felt has always been easy to find what I need, and easy to decipher how to use the corresponding classes. C# failed to displace Java as my favorite, and really only strengthened a dislike of Microsoft in me that you may learn to discover if you read my future blog posts.

Enter Ruby 3 and a half years out of college. During a Christmas vacation at the end of 2007, I decided to tackle Haskell, but was also itching to try Ruby. I abandoned Haskell before really learning about what Monads were all about... I enjoyed the language, but Ruby was secretly calling to me. When a language like Ruby calls, you listen. Ruby quickly proved why there was so much disdain for Java in the dynamic programming languages camp. I can't describe it as anything else but "fun." I have read many times that the language was DESIGNED to be "fun" and it all made sense once I had taken the leap.

I started blogging because I have been reading blogs from such prominent authors as Jeff Atwood, Steve Yegge, Joel Spolsky, and the hilariously painful articles presented by Alex Papadimoulis. These blogs have inspired me to put out my thoughts, opinions, and observations of programming out in the wild, for better or worse. I am still a young developer (3 and a half years experience), but I have a thirst for more that I sadly don't see in many coworkers (at least at my current job).

What should you expect to see in my blog? Right now I want to talk primarily about my experiences with Ruby and Java, and why you should stop claiming Java is the best language there is and reconsider those dynamic languages you might be bashing at various other blogs or forums. It's tired and repeated over and over from many people, but I think we will see that our collective programming future will move away from the likes of Java and C#, towards the likes of Ruby, and Python.