Wednesday, September 3, 2008

Language Remix

I stumbled across an interesting paper on polyglot programming here.

I am convinced more than ever that in the war of programming languages, it is impossible for one language to outshine others. So should we start looking at things differently? Should we move our focus away from trying to pick a winner?

A few trends are worth taking note of.

- Developers are not scared anymore to experiment with different programming languages and styles. While they still have favourites, they are increasingly using the most suitable language or tool for a given job. This is a welcome change from the days when we were 'shoehorning' every solution into one tool or technology.

- IDEs allow one to seamlessly integrate different tools and technologies into one platform.

- Virtual machines have brought the languages closer to each other in such a way that the language has become merely a tool for expression. Code written in one or mixed languages produces the same byte code so the run time environment has become language agnostic.

These trends suggest that the time is ripe to try out a polyglot approach to development and see if it has any real benefits or not. The paper above makes a convincing argument in favor of polyglot programming.


Friday, August 29, 2008

Fluent Interfaces

A Fluent Interface is a design construct that makes your interfaces read like natural language instructions.

I kinda like how a little refactoring of method signatures can make an interface much more "interesting", shall we say ? The idea is to make the interface read more like English. So, for ex., instead of

//<>
Aggregator a = new Aggregator();
List l = dao.getfeedFromEurope();
List l1 = dao.getfeedFromAPAC();
List l2 = dao.getfeedFromAmericas();
a.aggregate(l);
a.aggregate(l1);
a.aggregate(l2);
a.setFilterPolicy(FilterPolicy.NonPayingCountries);
a.filter();
List l3 = a.getFeeds();
...


you'll write

Aggregator a = new Aggregator();
...
List l3 = a.aggregate(l).and_aggregate(l1).and_aggregate(l2).filterWith(FilterPolicy.NonPayingCountries);



Neat, isn't it? The Aggregate class methods are self-referential. In the above example, and_aggregate() just calls aggregate() internally. But the goal here is to improve readability of the interface. Of course, like everything else, fluent interfaces can be overused or misused. You can, for ex. make a very verbose interface or worse make all the interfaces fluent.

I had a difficult time explaining this construct to the code reviewers last time. I guess it takes some time getting used to this style.

The first class

The snippet below prints the first class in the stacktrace. Might be useful for logging in some situations.

public vid test ()
{
Throwable th = new Throwable();
stackTraceElement[] ste = th.getStackTrace();
System.out.println(ste[ste.length -1].getClassName());
}

I live inside Eclipse

I have a fetish for Eclipse plugins. I use
  1. Mylyn for tasks management. Super-cool productivity plugin.
  2. Database Development Plugin. Replaces crappy DBArtisan on my desktop. Lets me perform basic database operations easily. Lightweight and super-fast.
  3. Azzuri clay Database Modelling plugin to create ER diagrams and generate DDLs from them; a basic feature that Micro$oft decided not to provide in Visio Professional edition.
  4. Beyond-CVS to integrate beyond-compare (my favourite comparison tool) with Eclipse.
  5. QuickREx for those esoteric regular expressions. I don't miss RegEx buddy now.
  6. Remote System Explorer for connecting to linux machines and running telnet/ssh/ftp shells.
  7. Eclipse web browser. Limited in features but helps during basic debugging or investigation when I want to search for an inexplicable ibatis error or how to convert dates to varchar and vice versa in the database (i always keep forgetting that). Also for keeping an eye on the latest on reddit :-). Wish it offered tabbed browsing.

My wish List

  1. A Mind map plugin to let me gather my thoughts.
  2. More powerful text editor. I use block-editing heavily.
  3. A plugin for MS Outlook that lets me attach emails to Mylyn tasks.
  4. A plugin for MS Excel
  5. A powerful desktop indexing and search plugin.

Amen.

Wednesday, August 27, 2008

Random Thoughts

Xtreme Programming is not a synonym for planning-less programming. It is not a euphemism that poor management can hide behind.

Xtreme is an ideological change and should be a conscious decision.

Ternary logic in SQL

A fellow colleague ran into a strange problem recently with a "not-in" SQL query. There were two tables, say A and B and we weretrying to get all values of a column from table A that did not exist in Table B.

Here's a result of the queries we ran.

select count(distinct column1) from A
-----17567 records

select count(distinct column1) from B
-----10234 records

So to get the values of column1 that are in A but not in B, we tried,

select distinct column1 from A where column1 not in (select distinct column1 from B)
-----0 records


Funnily, the query returned no records. Something was wrong.

After breaking our heads for several hours on this problem, the culprit turned out to be some null values in table B.

We changed the above query as follows to make it work.

select distinct column1 from A where column1 not in (select distinct column1 from B where column1 is not null)
-----~8000 records


SQL implements what is known as ternary logic for handling NULLs. I found a lucid explanation of this problem here.

Thursday, July 24, 2008

My experience with unit testing

I am not new to programming but have had bad programming habits for too long. "Enough is enough", I said to myself one day and decided to use a test-first approach for the next project.

Here's what I experienced.

1. Although I created the test cases before writing the classes, I didn't keep up with the policy for long. I found it a little distracting to think of and write a test case before any change to my code. The result was that soon my test cases were totally out of sync with the code.

2. It is difficult to be disciplined enough to keep test cases up to date specially when you are working with tight deadlines. Effort estimation must take into account this fact.

3. I had to continuously refactor my code to make it more testable. Writing test cases turned out to be a great way to write well formed APIs and good code in general. I had to make several modifications to my initial design to allow dependency injection. Moral of the story - automated unit tests can't be implemented as an after thought.

4. I found it difficult to test private methods and had to change their visibility to test them.

5. I found it difficult to automate everything. There were times when I just wanted to print the values of a hashmap and inspect manually. I found it too time consuming to completely automate the testing in such cases. Perhaps it's a case of old habits. But I realized how much of our testing is based on manually inspecting the results. It is difficult to break this habit and to learn to rely on automated test results.

6. Mocks are confusing (jmock) but very very helpful.

7. Seeing the unit tests run successfully didn't give me much confidence except for the first time when I ran them with fresh code. I can think of several reasons for it. Firstly, as I mentioned before, manually verifying the results of a testcase gives one a confidence that's difficult to achieve by running automated tests. There is something reassuring about seeing the results with your own eyes. Secondly, my test cases were not comprehensive enough to test full functionality. So after some time, I didn't see much value being added by running these tests. And lastly, I was coding for a database intensive CRUD application; my code was heavily dependent on file i/o and database access, both of which needed extensive integration testing. After a while, the unit tests were rendered completely useless and I was hardly running them.

8. There is only so much that unit tests can achieve. Most of the bugs in my code were caught during integration testing. But I must admit that at least some of these could have been caught during unit testing if I had better unit tests.

10. There should be a set of integration tests that check essential functionality. These tests may not run during the continuous build but must run during the nightly build.