Wild Man's Shore

Monday, March 20, 2006

The Enterprise - boldy going where ?

James Mcgovern's article on Ruby (and by extension, I guess Python, PHP, Scheme and other possible solutions out there that don't begin with J or end in a hash) can be distilled into a single sentence:

Ruby ain't ready for the enterprise because the big enterprise consultants haven't noticed it yet.

I guess James is an enterprise expert so he must know what he is talking about. I am not going to argue with him, but the article got me thinking:

What is the enterprise ?

This is a term that over the last half-decade or so (maybe longer) has been used to promote or disparage various languages, platforms or frameworks. "It's a toy language, not ready for the enterprise", "Microsoft servers are OK, I guess, but not really for the enterprise, like Solaris", that kind of thing. What is this mighty enterprise ?

Let's ask Wikipedia:

Psychology

  • an attitude or a character trait conducive to undertaking bold ventures or actions, especially ventures involving risk
  • a bold venture, particularly one of exploration or one that seeks inordinate profit
  • "Boldness, energy, and invention in practical affairs." (according to DANFS
So the word "enterprise" conjures up daring-do, courage, initiative, energy. Go Enterprise !

And further:

Economics and business

OK forget rent-a-car agencies, spiritualists and US Marine colonels with suitcases of used dollar bills: an enterprise is basically any kind of company or commercial entity. In marketing and IT firms, it refers to a large company: what in the US they may call "Fortune 100" or in Finland a few companies like UPM or Nokia. Enterprise therefore in this context means "big company".

What James is therefore saying is that big companies require enterprise solutions. An enterprise solution is therefore one that is specifically designed for a big company.

What does a big company require ? What the difference between, say, General Motors and Joe's Auto Repair Shop ?

* Number of employees: in the thousands
* Number of customers: in the millions
* Layers of management: more than the number of steps in the Great Pyramid of Cheops
* Speed: like the Titanic in an ocean of treacle

Yet both are businesses, both follow the same basic laws of economics. Maybe GM has more political power than Joe's Auto Repairs, but at the end of the day they have profits, costs, customers, expenses.

The core difference, though, is that Joe is focused on getting work done: fixing customers' cars and changing tyres and oil. He wants to get jobs done, payments in, bills and salaries paid. He is focused on results. Big companies, beholden to shareholders are focused on short-term profits too, especially their CEOs; but their layers of bureaucracy are more interested in processes and paperwork: CYA. CYA is the single most important thing about the enterprise (and funnily enough and completely self-contradictory, "enterprise" solutions are also applied to government agencies too !). THAT is why Java and C# and waterfall development and Oracle rule. As James says, it's not about results, success, productivity, customer satisfaction, quality, all of those things that make our lives as both users and developers a little bit happier. It's about following standards, even when those standards are like old roadsigns pointing to a collapsed bridge.

I'd rather make Joe and his customers happy.

It's a consultant's life

This month I took the plunge into consultancy, leaving the shores of a paid salaried position for the choppy seas of the private consultant. Immediately I became inundated with work, hence the reason for not blogging lately. The hours are crazy: I work at home most of the time, so I get to be a full-time dad for our one year old, which means I start work in the early hours to avoid distraction (my wife is a baker, so she often starts at 3 in the morning) or late into the night. Only now am I getting my sleep patterns into something regular. Plus, I do work for overseas clients so I often have to work to their time zone.

I have a "toiminimi" ("working name") which is a kind of private, one-man company, for handling the billing; this cost 70 euros from the magistrate's office. A few rather obvious points:

* Get an accountant ! People who mess up their taxes lose big, from what the Finns call the "tax bear".
* Set up a separate account for handling customer bills and company expenses.
* You have many bosses as opposed to one boss.
* And these bosses don't pay a regular salary ! You have to bill them for time/results.
* No results, no pay !
* No office politics, but can be lonely
* "Think globally, act locally" : if you work in the net there is work around the world. Not all development is done by bug big outsourcing companies.

It's fun from a development point of view. Most places I have worked you tend to not only work in one language/framework but on one product for months or years on end. Now in a single day I do Python, Ruby, PHP and SQL in a variety of projects. But there is extra stress, working at home with all its distractions and knowing if you screw up or miss a deadline you don't get paid.

I'm going to do this for a month or so while I wait for some job offers so I can compare how much money is coming in from this.

It's quite an adventure.

Saturday, January 21, 2006

Problems with Finnish Keyboard and Ruby's irb

I ran into a problem with Ruby's interactive shell, irb, on Windows XP: it did not accept alt-gr generated characters with the Finnish keyboard, which prevents you from typing characters such as [ or @. The solution was found here:

Basically create the following file, .inputrc, in your home directory(C:\Documents and Settings\<username>):

"\M-[": "["
"\M-]": "]"
"\M-{": "{"
"\M-}": "}"
"\M-\\": "\\"
"\M-|": "|"
"\M-@": "@"
"\M-~": "~"
"\M-$": "$"

Then add the following line to the start of <ruby-dist>\bin\irb.bat:

@echo off
set HOME=%HOMEPATH%

and it should work fine. A real showstopper, though, which I haven't seen in other tools (such as Python's shell).

Friday, January 20, 2006

Finnish elections

As a Brit living in Finland I have as much a right to vote and comment on the elections as Conan O'Brian. The election has gone to a second round as the incumbent socialist candidate Tarja Halonen did not get enough votes for a 50% majority, so now the contest is between her and Sauli Niinistö who represents the Finnish conservative party (Kookomus). He may get most of the Center Party candidate (current Prime Minister Matti Vanhanen) votes as the latter has endorsed him.

The Finnish president is expected to be something of a neutral figurehead, like a British monarch, and the post has lost much of its power since the Kekkonen "dictatorship" of the sixties and seventies. At the same time, as a politician, people feel the president should express opinions and show some kind of leadership, and Halonen has been criticized for her lack of these qualities. Her re-election looked like a shoo-in last week; now it's going to be a much closer race. Niinistö is a dry, lawyer/banker type noted for his one-time relationship with Finland's Minister of Culture, the former Miss Finland Tanja Karpela (as indeed has Prime Minister Vanhanen; one could play a game of Seven Degrees of Tanja Karpela in Finnish politics). Halonen is (or tries to make herself out to be) a motherly, kindly Moomin Mama, but often her true colours come out, with a reputation for bullying her co-workers and her husband in public.

Many Finns put down "Aku Ankka" on their ballot paper as a kind of protest. Aku Ankka is Finnish for Donald Duck, who is considered a hero by Finns for his "sisu" (rough translation: bloody minded tenacity against all the odds). Personally, I would vote for his uncle, Roope Setä (Scrooge McDuck), as I think he would run a much tighter fiscal policy and would reduce the ridiculously generous social security spending in this country.

Wednesday, January 18, 2006

TurboGears vs Rails

I first glanced at Ruby a few years ago, round about the time I first glanced at Python. The two were, at least superficically, similiar. As I was more heavily into web development at the time Python looked the better option because of Zope, WebWare and other packages; Ruby then (as far as I know) just had plain CGI.

Now Ruby has stormed the web development world with the Rails platform, leaving Pythonistas dazed and confused. Nevertheless we rallied round two excellent packages, TurboGears and Django, while the Zopeheads worked on their interesting but rather esoteric Zope 3. And Python is not short of web development platforms; I wrote a large document management application using Quixote + Durus, about which more later. But Ruby, once an obscure Japanese cousin to Python, is now the darling of the tech media.

Rails has been around now for about 15 months, 3 times longer than TurboGears (though not TG's individual components) and so I decided that as a more stable platform it would be worth a look. Plus, and this is something I forgot to mention in my last post about Java, you should always look for possibilities to beef up your resume with buzzwords. Even if I just wrote a little wiki for handling work projects in Rails I could put that on my CV. Such is the benefit of hype.

Others have written on the differences between Ruby and Python; I'll not add to that here, except that it was in a way harder to switch between Ruby and Python than between Python and Java, because the small differences in syntax keep catching you out. Anyway, on to Rails.

The immediate first impression is that TurboGears is more verbose(or explicit, if you like) than Rails. For example:

RoR:

class NewsController
@articles = Article.find_all end

end


TG:

import cherrypy
import turbogears
from turbogears import controllers
import model

class News(controllers.Controller):

@turbogears.expose(template="news.templates.index")
def index(self, **kw):
return dict(articles = model.Article.select())


One thing to note is how you have to tell TG what methods to expose to the web, which template to use, and what data goes in the template. In RoR this is decided for you; every method by default is exposed, any data in the method goes in the template, and the name of the template is the same as that of the method (in this case, index.rhtml). You can override these, but a lot of assumptions are made on your behalf.

Let's look at how each system handles the model:

RoR:

class Article < ActiveRecord::Base
end

TG:

class Article(SQLObject):

title = StringCol(length=200)
maintext = StringCol()
created = DateTimeCol(default = datetime.now)
category=ForeignKey("Category")
author = ForeignKey("User")


Again RoR's ActiveRecord works implicitly: it looks for a corresponding database table and maps rows to Article objects. With SQLObject you define the columns in Python code and then the object creates the corresponding database table as needed (in this case, Article.createTable()). You can do things the RoR way in SQLObject, but in general this is only done with legacy databases.

This is the basic difference in philosophy between the two platforms. The Pythonic way is "explicit over implicit". Everything is out for show: you know what modules are imported, you know what methods are exposed, you know what columns are defined and so on. It may take more keystrokes but the extra code let's you know what is happening when things go wrong. The Ruby way (or at least the Rails way) is the opposite: take the burden off the developer, don't bother them with the petty details that get in the way and add to the line noise.

RoR does make for more readable code. However, there is a caveat: when things go wrong, or when you want to do something different, it's a lot more work to fix the problem than if it's always obvious what's going on. In that way RoR is the anti-J2EE; it assumes everything for you. I can see the advantages, but I also find it annoying and presumptious: I want to decide upfront what methods to expose and how my data model should look. In fact, Zope has inspired such hatred amoing Pythonistas for just that reason: things like acquisition doing mysterious business behind the scenes that cannot be explained, which is lovely when it works but a source of immense frustration when it doesn't.

Finally, one should also consider features available in TG that are not in RoR and vice versa. TG has the Toolbox, an over the web admin application that comes with a set of goodies like a relational model designer and data browser, localization tool, and so on. More importantly, it has good internationalization support, including localized date formatting and the like. This is really, really important if you work in Europe: in Finland,for example, I often have to develop sites that are available in Finnish and Swedish (Swedish is Finland's second official language) as well as for example English, Estonian and Russian. I'm not sure how well RoR supports internationalization.

Both have form widgets, though in different ways: RoR just uses simple functions in templates, whereas in TG you create form and widget objects and insert them into your templates. RoR uses ASP or PHP style text-based templating, TG uses Kid, an XML-based template engine that ensures well-formed HTML or X(HT)ML. RoR has scaffolds, TG has DataControllers. Which features you need and which is the better way of doing things is again down to requirements and preference.

In summary, both are well-designed and fun to work with. Both kick Java's fat corporate ass. They have different approaches to the same problem, but that's OK:I like the Pythonic way of TurboGears but I can see that others prefer RoR's magical implicitness. RoR has better marketing which makes it easier to persuade your boss to let you use it. It is also more stable, being in existence 3 times longer than TG, but TG makes use of well-designed, mature components like CherryPy and SQLObject. Python has more libraries than Ruby, Ruby has nice features for closures and the like. As always, YMMV.

My next comparison will be TurboGears vs the various Python web development frameworks.

Tuesday, January 17, 2006

TurboGears vs Java

I have a large, upcoming project looming at work; no details can be revealed at present for confidentiality reasons, but it will be fairly high-traffic, and it will have a lot of features.

As a TurboGears contributor I immediately thought of using this platform for the task: it has everything the project will need, for example localization (must support English and Finnish), identity management, etc. However, it is still unstable (coming up to version 0.9) and in the interests of the customer I felt I should investigate other possibilities first.

I did some Java programming a couple of years ago, mainly non-web/Swing stuff but also some servlet work with Velocity and plain JDBC. One of the requirements is that the application may have to integrate with a third party tool which happens to have a Java API, so Java may be a fine contender.

Looking at the Java landscape today after years of PHP/Python it's quite clear that J2EE, in the sense of web tier + EJB, is hardly in use any more except perhaps in the largest of companies. The most popular solution (going by blog posts and discussion groups, I have no idea about real world usage) seems to be Spring + Hibernate. Digging deeper I followed an excellent Spring tutorial to get started.

Spring has an ambitious scope, but the part I was looking at, Spring MVC, is fairly straightforward: it uses the Command pattern, each command class represents an "action" such as login, checkout, do search etc. Hibernate is again a pretty straightforward way to map relational models Java objects. Spring can be used with JSP, Velocity, Tapestry or some other presentation layer.

Localization is well supported in Java, and I liked how it was taken as granted that you need localized messages, unlike in PHP or Python where (despite huge numbers of non-Anglophone developers) it seems more of an afterthought. Certainly that is the impression I got when I wrote the i18n package for TurboGears. For example, handling Unicode in Python is a real pain. GNU gettext is supported by Python but somehow the Java localization system seems a lot simpler.

One thing that came to mind however was the sheer verbosity of Java. I had forgotten just how much line noise is required to even do the simple stuff. I don't mean the core syntax as such but the tendency of Java developers to fly into a stratosphere of abstraction layers. Along with the countless number of XML files I can see why Java developers love (or need) their IDEs so much; even for a simple tutorial application the mind-boggling number of abstract classes, interfaces, XML configuration files and so on and so forth left me wondering how a single person could possibly keep track.

Nevertheless, Ant was nice once it was up and running; compiling and deploying to Tomcat and restarting Tomcat could be done with a single command. A little more work there than,say, reloading a PHP-generated page in your browser, but not oppressive. And catching compile-time errors was a time-saver.

That's the good thing about Java vs. Python or Ruby; its boring predictability. But why the love of abstraction ? In TurboGears, for example, you have a SQLObject class for your model, say Product. It may look something like this:

class Product(SQLObject):
description = StringCol()
price = CurrencyCol()
quantity = IntCol()
category = ForeignKey("Category")


That's it. 5 lines of code and your class is done. You can access it in your code for example like this:

# get all products costing less than 10 euros

cheap_products = model.Product.select(model.Product.q.price < 10.00)


The equivalent Java code may exist not in 5 lines but 5 files, for instance:

  • Product.java : plain Java object to hold data
  • ProductDao.java : interface for accessing Products
  • HibernateProductDaoImpl.java : Hibernate-specific implementation of ProductDao
  • ProductService.java : class which accesses ProductDao interface and returns Product instances
  • Product.hbn.xml : Hibernate XML mapping for Product to relational table

Now granted the added abstraction gives you greater flexibility down the line: if in the future you decide to replace Hibernate with TopLink or some other ORM, or you get your products from XML or flat files or over a web service, you don't need to gut your code across the board, just drop in the new classes, change some XML configurations, and you're done. The equivalent SQLObject code in Python works for a number of relational databases but any more significant changes (e.g. another ORM or entirely different storage layer) would require recoding parts of the app. Of course you could write a Python application with a similar degree of complexity (Zope3, I'm looking at you). But such abstractions in the Python world are uncommon.

In the real world, however, how often are you going to change your storage layer ? For example, if I'm building an online store I design the relational model to a T and go out and set up a database, say Oracle, and design the application to talk to that. That is the part of the system that is least likely to change.

Of course Java developers would accuse me of over-simplification, and they would probably be right. And Java developers earn a whole lot more than Python developers, so maybe they have a point :-)

Next post: comparing TurboGears and Ruby on Rails!