The Quirk factor vs. Sustained Complexity
More useless discussion about computer languages
Posted by 11/15/2006
Apology
The last thing I want to do is disparage the work that anyone is doing, discourage anyone from using Ruby, or try to declare any winners in the language wars. I'm just a mediocre programmer trying to write mediocre programs.
Homage to Perl
First off, in my previous post I said something like "Ruby is squeezing through the keyhole Python made..." I have to say in retrospect that is wrong. Both Python and Ruby owe their existence to Perl. I was never able to read Perl code. But Perl and CPAN and the like really changed the world - and Python and Ruby are riding on the energy from that initial wave. I do believe that Ruby is going to end up duplicating a lot of what Python has done. And in that respect, Python is leading the way. Although maybe someday Parrot will rule them all.
My experiment this year
During the past year about 95% of all the code I've written I've written twice (that's some kind of weird pun "I've written I've written twice"). Once in Python, once in Ruby. Sometimes I even go back and forth a few times because one language will give me ideas for the other one. These have been modestly sized projects - so roughly 10,000 lines of code in each language overall. Why have I done this? Mostly to compare the 2 languages. Languages are religions. So if I'm going to advocate a religion I want to know the religion.
How long does it take to learn a language?
In some ways this is an easy question. It only takes a few weeks to learn syntax. But knowing a language is knowing 1) History and conventions 2) Where and how to find answers to questions 3) How to use other peoples code 4) The standard and not-so-standard libraries. In that respect I think it takes a year to be perfectly comfortable and fluent with a language.
It all boils down to...
So far I look at my Python code, I look at my Ruby code and I notice no significant difference. I can get the same things done. But what I've noticed is that the bigger a Python project gets - the quirkier it gets. In contrast, the bigger a Ruby project gets - it seems to just stay the same. It is only more code. It is not collapsing under its own weight. The small parts resemble the big parts. It seems better at handling complexity. I would call that quality "Sustained Complexity". This is a remarkable quality really. And I can't quite explain it. It is likely because of the underlying object-oriented flavor of the language. And the easy meta-programming.
A good thing
In Ruby the top of my classes are like preludes or introductions to a book. This is something I like a lot:
class Handbook < ActiveRecord
include InventoryItem
attr_accessor :title, :subject, :abbreviation
has_many :assignments
is_indexed
has_generated_key :module
that kind of thing. It is like an introduction.
It reads:
"I have a Handbook object that has all
the methods of an ActiveRecord and an InventoryItem.
In addition it has title, subject and abbreviation properties,
has a collection of assignments, is indexed and
has a generated key"
Java really needs something like that.
Class annotations don't quite do the trick (I don't know
if this is actually possible. I haven't used
Java annotations - but I'm guessing it would be something
like this):
@IsIndexed
@HasGeneratedKey(key="module")
@HasProperties(properties=["title", "subject", "abbreviation"])
@HasMany(name="assignments")
public class Handbook extends ActiveRecord implements InventoryItem {
}
Which would read like this:
"...This is indexed. It has a generated key. It has the properties
title, subject and abbrevation. It has many assignments...
This is a Handbook with all the methods of an ActiveRecord
object and an InventoryItem (see above for more details) "
This is backwards, like a foreword before the title of the book.
It disrupts code reading with strangeness
that has yet to be explained. I don't like it at all. I don't like
Python decorators either, but that's a long story. It only gets
bad when there are multiple ones - and Python doesn't have them
on the class level. So the common scenario is this:
@require_login def show_handbook(request, id): handbook = Handbook.get(id) return handbookWhich reads "call require_login on top of the show_handbook function" which isn't all that bad I suppose. And Python has the meta-programming thing, so the language allows this sort of thing:
class Handbook(ActiveRecord, InventoryItem):
assignments = meta.hasMany('assignments')
isIndexed = meta.indexed_item(True)
key = meta.generatedKey("module")
def __init__(self, title=None, subject=None, abbreviation=None):
self.title = title
self.subject = subject
self.abbreviation = abbreviation
The Quirk factor
Besides Python has what I will call "The Quirk Factor". This is easier to explain with an example: Many years ago a friend of mine described playing some kind of war game that was sort of like paint-ball. He said they had to memorize a phrase they would yell out to identify which side they were on. He found it was easier to remember something weird and long like "Watermelon" rather than "George". In other words, it is easier to remember quirky things than simple things. And I think this is both the strength and the weakness of Python. It is quirky. It requires remembering strange things. But I think that can be good sometimes. But only sometimes.
Which one?
So, given that the languages are roughly equal, how do I decide what language to settle on? If I have to settle on one? Well, then it comes down to stupid things like available libraries and performance. And that's where Python wins for now - and that is why I'm frustrated with the state of Ruby. I would rather decide on the merits of the language. But one thing I have to do is a lot of xml processing and here Ruby fails me. Another is that I've gotten fond of the Fltk package. There is a useable python binary for that, but not Ruby. Another problem is everything I write has to work on Windows™ and there Ruby fails me again. Fltk and libxml both have Ruby bindings, but not Windows™ binaries. Then there is stuff like SciPy, Python Subversion Bindings, Beautiful Soup, Peach, NLTK, PIL, wxPython just to name a few. There are all very useful and have been around a long time and seem dependable. There are often Ruby equivalents in a half-way state. I can get anything working in Ruby I can get working in Python, so it is not limiting in that way. But I'm always disappointed with the speed. Consistently I'm finding that things that are acceptably slow in Python, are unacceptably slow in Ruby. I can give examples, but I don't think anyone would even be suprised by that. Which is part of the problem.
I'm tired of it
All in all though, I'm tired of it all. Everybody and their dog
has an opinion. I can't say one
language is better than another, one editor is better than
another or one web framework is better than another. It is
impossible to say. And it is part of the programmers sickness
to even think there is an answer. It is probably because we
work with a system that is entirely based on "yes" or "no".
I do like the Ruby language. I like a lot of the syntax
I like the easy metaprogramming. I like being able to name
methods with ! and ?. I like the useful lambda
which enables me to condense a function in one place, where
it is called - which, to my mind, improves readability.
Python insists on named function. But there again, sometimes
that's good. And sometimes Ruby is way to clever for me.
The (&:symbol) trick for instance.
Things I wish Python would steal from Ruby:
- allow ! and ? method names
- Parse an entire file so I can declare methods after I call them. This may seem strange, but it would be a roundabout way around the lambda problem for me
Comments
Post a comment