2 June 2009

Successful crap

It never ceases to amaze me peeking into various successful open-source projects, seeing the innards, and wonder how they even got this crap code past their own pride. Yes, I need to vent.

This weekend I was head-down in various content-management systems and their ilk, digging into anything from WordPress to Habari to Joomla to Simple CMS (which you would expect be simple) eZ publishing. All of them had rather abysmal code scattered throughout (with eZ publishing being the better of the lot), oddities, and all the worts you'd expect of systems hobbled together, where their success is more an afterthought.

But hang on, I can't criticise systems for their organic growth. But I can criticise them for not doing much about the trouble that comes from it. Sure, I understand that rewriting core parts of a system requires a huge ego and nerves of steel, and I understand how "if it ain't brok, don't touch it" rules the end of the day, but surely the end means is good software, right?

But.

It's crap. It's rubbish. And more importantly, as I can put up with crap if it gives me opportunities and love, it hinders innovation, flexibility and, well, love.

Let's pick on a random contender that I worked heaps with last week, WordPress. If we cut away comments, this is its index.php ;
define('WP_USE_THEMES', true);
require('./wp-blog-header.php');
If we look into wp-blog-header.php, here's what we get ;
if ( !isset($wp_did_header) ) {
$wp_did_header = true;
require_once( dirname(__FILE__) . '/wp-load.php' );
wp();
require_once( ABSPATH . WPINC . '/template-loader.php' );
}
Ok, so let's peak into wp-load.php, and we find about 20 lines of code and more includes. Don't you just love playing hide and seek with files to find out where it's going and why? These things maybe have come around from shuffling the organic growth of the system into other files, and left them with these sad little snippets that's hard to get an overview of and takes a slight performance toll, too, as well as eat away your sanity and good programming ethics. And they all contain that newbie error of putting this at the end of every business logic file ;
?>
It's not needed, and if you like your whitespace under reasonable control, you're stuffed. Not a big crime, mind you, but just one of those niggling little things. Then you've got functions and objects, some with the wp_ prefix, some without, business logic in files called wp_settings.php, repetition of code everywhere, hundreds of DEFINE's scattered about in different files, and so on and so on. (And yeah, I should contribute as it is open-source and all that, and I'm actually writing a embedded Topic Maps engine as a plugin, so we'll see)

But I'm not here to pick on WordPress per se. It's more about how this organic growth hinders innovation and opportunities. So let's talk about frameworks. All little pieces of code together form a framework, so we're not necessarily talking about a framework of disjoint classes or functions that aid developers making stuff like the Zend Framework, or Cake, or Symfony, or CodeIgniter, or 1000 others out there. Well, kinda; all those little things the app is made from also constitutes a framework, but it isn't disjoint nor refactored or synergetic or stable or well thought-out as you get in a more established framework, but never the less that's what it is.

PHP itself is a framework, of course, and most PHP frameworks are wrappers and added code to make PHP act more like a coherent system, fixing inaccuracies and bugs and niggles, stabilizing behaviour and increasing the need for spending hours and hours learning some new paradigm you can't use elsewhere.

Hmm. Where was I? Oh, right; every app is a framework. But when the framework isn't a perticulary good one, where the pieces are either too fragmented or too disjoined to make any sense, making stuff in that framework is going to be a pain. Like WordPress is a pain. And before you know it we get to the next rewrite, and this time we'll get it right, although we need to keep our legacy intact, and hence we write hacks on top of fresh code to drag it back to the hole it came from. The data model needs to rewritten, but it won't because "well, it works, doesn't it?" and the framework needs to be rewritten, but it won't because "well, it's not broken!"

When I can't replace MySQL with something else, that's a hindrance. If I can't change the way tagging works, I can't move forward. If I can't change the URI handling, I'm stuffed. If I can't use portions of it to write something else, nothing new will come. Sure, there might be a plugin architecture somewhere, perhaps a simple event model that one can tap into, but if I can't replace the model in which it operates I can't make it more beautiful. I am forced to accept the model and framework in which WordPress sits.

And it sits quite squarely on top of everything I want to do. I want to create better and typed links, I want to reuse a model for sequences and storage, I want to replace tags with guided controlled vocabularies (maybe even typed and binary linked to external WordNet sites), I want to use it as a CMS and skip the URI handling alltogether, and so on. But I can't, because WordPress wasn't designed with change and innovation in mind.

But a day will come when even the most successful project will face its own innards. And some people will branch it, some will stay on, some will create something new, and some will stop using it alltogether. And it's all a really good thing; this is organic growth, it's a framework that spawns other frameworks. And more crap will be successful. Things will be broken and ugly and hackish, just like some things hopefully won't.

And in a few iterations, something beautiful - with a probably different name - will emerge.

Update: It would be great to get your suggestions for open-source projects which are designed for change and has quality and / or elegant code to boot. Let's make a list!

25 May 2009

How to stop thinking in code

A while back user TStamper on StackOverflow wrote a question which I've struggled with in the past ;

How do you clear your mind after 8-10 hours per day of coding?

Have you struggled with this, perhaps as a young developer? How did you overcome it? Can anyone offer general advice on winding down after a long programming session?
Now, unless you already know, StackOverflow is a brilliant place for developers to ask and answer questions about programming and related stuff (Joel from Joel on Software was one of the startup guys, a brilliant guy I've had the pleasure to meet at some geeky event in Oslo a few years back). Even the question above was on the edge of that criteria, so that's how hardcore the programming focus is. However, I did write an answer based on years of experience with a brain that never seem to shut down which I'd like to share, because only yesterday I was once again asked this very question, so I need to share ;
I use the last 5 minutes of my day to write myself a debrief note for the next day. This will do three important things;
  1. It takes your mind off the complexities as the debriefing will be a short form of all the things you've worried about, and helps clear the mind of all the what-if things.

  2. If your mind have a long down-settling time, the debrief note is the perfect place to use for a central of "things I forgot about" or should note somewhere. The debrief note becomes a knowledge central for whatever you did that day.

  3. It focuses your mind on the real issues. One thing is to clear the mind, another is to let it keep going, but more focused. So even if your conscious mind is letting go, it's probably a good idea to let your unconscious mind keep churning at the problems, and a good way to help your mind do this is to be slightly futuristic in your notes (thoughts on direction, for example).

Read the rest and fuller response at StackOverflow.

21 May 2009

Weird coincidences

On Sunday me and the family went to Sydney to celebrate 17th of May, Norway's national day. I was looking forward to resupply myself with things I can't buy in the shop, and hopefully catch up with someone else who speaks my freaky native tongue.

We went to Circular Quay to see the parade, and then took the ferry to Manly to get to the Norwegian Seaman's Church where some more festivities would take place, some more fiddle music, a speech or two, and cakes, and waffles, and sausages, and caviar on tube, Lofoten sauce packets, salty liquorice and other assorted funnies and yummies.

At the church we lodged ourselves in an area fit for children, mommy looking after Sam while daddy stood in queue for an hour getting the goods. Getting back to them with said booty, I entered into a conversation between my wife and some other mothers about. All of these women were Aussies with some Norwegian connection, and at the centre of this discussion was a woman who was "a violinist", and a few enquires later and my brain realigning itself that, holy Mustard!, I'm talking with Myee Clohessy (and her daughter Freya), so I said I've seen her before ("yeah, right", I'm sure she thought), pointed out Salut Baroque and the fact that she played in Norwegian Baroque Orchestra with a good friend of mine, Anna Helgadottir (cellist). Then she remembered something and asked if I was a blogger, in which I said yes, and she was reminded of a posting she read of mine, bragging about a performance of her (and Melissa Farrow!!) and the Salut Baroque gang some years ago, and she had to tell Melissa about it. They both, of course, play in the Australian Brandenburger Orchestra of which I'm also a fan.

Talk about weird and wonderful. I joked that I should have gotten her autograph, but the more I think about it, of course I should have gotten it, and I'm beating myself for being stunned by the circumstances! I've seen Myee a few times and love her style (you'll notice her up on stage; she's the bendy-swayie one, in the sexiest meaning of that made-up word), so how often does a guy like me, living down in the Baroque wastelands of Kiama, get to see their idols up close like this?

Exactly, I'm an idiot. I hope only that I get to see Salut Baroque again soon, in either Sydney or Canberra. Incidentally, and the reason I was reminded to write this post, is that they are having a concert on tonight in Canberra and I'm jealous of anyone going and sad that I'm not.

15 May 2009

Spilling a few beans

I think enough time has passed, don't you? I've been hinting to what I'm up to these days, but I've been rather careful about spilling the beans, I guess because, well, it's a brand new adventure and every storyteller should get their story together well before writing it down. I'm keen to talk about this stuff, though, because it is wickedly cool and I'm keen to not only do it, but to talk about it and involve more people in it as well.

As you probably saw from my last post I'm currently in India, and yes, my new employer is an Indian company, but I work from home (in gorgeous Kiama, Australia, 1.5 hours south of Sydney) and travel to India every so often (4-5 times a year as a rough guide). We work over the Internet, including video conferencing and remote controlling and the like, and as such is a new interesting challenge for me to be somewhat isolated from the smiles and sideways nods and the tacit knowledge floating down the hallways of our headquarters in Mumbai. I've got plenty of ideas of how to deal with that, so we'll see how it goes.

My company is Free Systems Technology Labs, a nifty medium-sized IT development company with main offices in Mumbai (from where I'm writing this) and most R&D and development in Bangalore (where I've been the last week), which is a daughter-company of another company mostly known for more hardware orientated stuff, like computer building, server hosting and various gadgets, but they only have a number of software outlets as well. I'll be working with anything from planning to execution, and mostly in the domain of Topic Maps. Yes, the very thing I've been talking about for the last 9 years is now going to be my main concern as opposed to secondary or third (or some periods not at all) at the whims of other jobs, and I can't even begin to tell you how excited the prospect of that is to me; I believe in the ideals and practice of Topic Maps so strongly, and it's going to be good for my soul to pour it into something as cool as what we're going to do. (More on that later) The guys here also happen to share many of my own ideals (open-source, development methods, goals, community and societal building, and so much more), and they've been spoiling me. I'll miss the tea, that's for sure.

I became part of this through a weird mix of happenstance, but mostly because the people involved here have been, put simply, a fantastic bunch, in terms of technical brilliance, sincerity and honesty, and in convincing me that I should join (they obviously think I'm good for something :). I've been with the company now almost three months where the first two months are more like a warm-up, but it's been a very good ride so far.

But I need to talk about something that's been on my mind ever since they got in touch with me last year, and that's prejudice. The world is full of it, and I entered this adventure with a slight degree of scepticism. No, not the bad kind, but a certain carefulness, because, you know, they're Indians, and Indians got their mouth full of rice, and you're not getting any! (A joke I got from an Indian friend, so that makes it alright, yeah? :) Not only did they have to convince me, but also my wife. "Honey, how about I drop my great-paying safe cushy job in one of the richest countries in the world, and rather work for strangers from a strange land full of poverty and strong smells and interesting hairdoos, and do it over internet?" Yeah, she was keen, as you can imagine.

You can't work for Indians! They are supposed to work for us!

Sure. But they kept talking with me, flew me to Belgium (they own half of a company there) and were not only completely honest with me but simply blew me away with their knowledge, seriousness, and most importantly their friendliness and openness. Me and the wife thought long and hard about it (probably longer and harder than my company wanted me to :), and here we are.

Everything I knew about India was either heavily adjusted, or simply wrong, but I've seriously enjoyed being corrected. I've embraced everything that's been thrown at me, including very hot food, weird drinks, amazingly crazy traffic and the sweltering heat, the chaos, the smells, the meetings and the way they interact, the attitudes and the values. I think the tagline "Incredible India" is truer than they think.

Ok, that's enough for a first intro, now I have to get to bed. I'm flying home tomorrow and I'm looking forward to seeing the wife and kids again (Lilje just won an award for her art at school, so I'm mighty proud as well), and we'll be spending the weekend together, and on sunday celebrate Norways national day in Sydney.

And then, a little bit later, I'll tell you about the wickedly cool stuff we're going to do with Topic Maps.

9 May 2009

Where in the world is Alexander?

Short answer; Bangalore, India.

Longer answer; my new employer which I started with a couple of months back is an Indian company with strong ties to back-end systems and support, hardware manufacture and design, and software services. I'll tell more as things progress, and I'll probably talk a lot more about how they plan to use Topic Maps to solve some really crazy and hard problems. But before I do those kind of detailed stuff, I wanted to just quickly show you this picture which pretty much summarises my first impression of this crazy, lively, contrasting, weird, interesting place, and if you can't read the sign, it says "Follow traffic rules." I realise that in India, if you ask kindly, they just might do what you ask, but riding as a passenger in a car through this traffic was, err, an experience I won't forget anytime soon. However, it's interesting that in a language such as my own (English, or Norwegian, or Swedish, or Danish) we base our expression mostly on words alone, while in India the reason traffic works is that they've got such a strong foothold in semiotics that makes it work. A honk here, two honks there as we pass a car, a blink of our beam lights racing past a "moto" (small scooter that's kinda rebuilt as a tiny car) ... I still have much to learn about this language. The cool thing is that it's global; even I can do it. Except I would never drive here. Never. Ever.

Anyway, I'm in India to train staff and meet and plan with them in all things black magic and drink their excellent Indian tea and eat their amazing food, and generally get a feel for the country, the culture, and most importantly, the people I'm working with, which so far has turned out to be a fantastic bunch. I'm here for another week or so, and I'll suss out the details and let you know all about it in due time. Until then, there's a chapati drenched in yummy chutney with my name on it. India is, truly, an amazing place.

P.S. Hey Barta, where can I get my sweaty hands on your TM as a filesystem? Would love a play with it right about now. Oh, and that near NLP query stuff you mentioned that one time in the back-alley while drinking gin and discussing the meaning of wife. Or life. Or whatever.

28 April 2009

Nightmare

Update: See bottom.

You know that sinking feeling you get when you're sitting in the root directory of your Linux box, trying to recover the system from a configuration mishap and slightly unaligned update, when you press Enter after typing in "rm -r *"?

Yeah, well, I kinda had a stressing day today. Well, it started yesterday with PulseAudio (the default sound server in the latest Ubuntu) not giving me the desired effect (which is, you know, sound), so in my infinite wisdom I chose to prod a little, configure a little and run various tools in order to fix things. Because I'm a bit of a noob when it comes to all things Linux and Ubuntu these days, little by little I chipped away the things that were working, ending up with a system completely broken.

My computer is a Toshiba Satellite P300. So, I upgraded Ubuntu 8.10 (which I have been very, very happy with) to the new and tasty 9.04. I tried to upgrade through the update-manager a number of times, but my internet connection is a bit flakey, so it panicked on me a few times. In the end, it kinda worked, and the upgrade happened and most things seemed to have worked, except that sound was gone.

So, I tried to make sound work again, because my new boss wants to chat with me over Skype, and it would be a bit pointless without, you know, sound. Somewhere in that process I killed sound completely, and it went from just noise to no noise at all. SO I thought that something was amiss in the upgrade, and so I played around in Synaptic (the package manager) for a while, installing and uninstalling sound stuff. No good results.

Then things got blurry. I got a hint online somewhere to boot into recovery mode and use apt-get from the command line, and run things like dpkg-reconfigure stuff. Well, at some point, and I can't think of where, someone pointed to a major reconfigure of the environment might work, so dpkg-reconfigure * went into action. Ouch, bad move, because when I returned to normal booting, the mouse and keyboard had stopped working. A reboot (well, a crash boot) later and a well-meant dpkg-reconfigure xserver-xorg further killed my graphics card, so now I was at the point of no mouse, no keyboard and no graphics.

I noticed while doing apt-get that it claimed some packages were installed automatically and no longer needed, and told me to uninstall them. Which I did, and before my eyes I saw things like "uninstalling dkpg-*" which is the whole packaging system, which would leave me stranded with a useless system without the tools needed to fix them. A very, very sinking feeling came over me.

However, the brilliant Ubuntu folks have a menu option for just this kind of stupid user actions, called "fixing broken packages" (or something like that). A run of that, and my system got apt-get again. I uninstalled xserver-xorg completely, and reinstalled it, ran the "xserver fix it!" option from the boot menu, and rebooted.

I got my graphics settings back, but still no mouse and keyboard, rebooted into recovery, found one package had been mangled called "udev", uninstalled and reinstalled, run the "xserver fix it!" again plus "apt-reconfigure console ... something", rebooted again with my mouse unplugged (thinking it might be an autodetection problem, and that plugging it in afterwards might reconfigure it properly), got the graphics and the keyboard working, plugged in the mouse which it autodetected and worked, I tapped in username and password, and friggin' VOILA! I was back to where I left off a few days ago.

With no sound.

But hey, at least I got my system back, and if nothing else my Ubuntu / Linux foo has increased, through manual backups and USB mounting and killing processes and linking up dynamic libraries and editing lots and lots of configuration files. Now, if only I can fix that sound, although I'll leave it alone for a few days before I venture down that path. And, I'll burn myself an ISO of my current system right now. Happy, happy.

Update: Got sound working; the rather common pitfall of having your PCM sound set to no sound. Slide it up, and voila! But my microphone is still dead, not sure how to fix that one. Possibly I need to install Windows, boot into it, unclick the mute button there (as it seems the Linux drivers haven't got some access to that), reboot into Linux and kill Windows again. Like, a 2 hour roundtrip because the mute on the microphone might or might not be accessible there. *sigh*

20 March 2009

Ressurection : xSiteable Framework

I've just started in my new job (yes, more on that later, I know, I know) and was flipping through a lot of my old projects over the years, big and small, and I was looking for some old Information Architecture / prototyping tool / website generator application I made with some help from IA superstar Donna Spencer (nee Maurer) back when I lived in Canberra, Australia.

I found three generations of the xSiteable project. Generation 1 is the one a lot of people have found online and used, the XSLT framework for generating Topic Maps based websites. I meant to continue with generation 2, the xSiteable Publishing Framework (which runs the Topic Maps-based National Treasures website for the National Library of Australia) but never got around to polishing it enough for publication, and before I came to my senses I was way into developing generation 3, which I now call the xSiteable Framework (which sports a full REST stack, Topic Maps. And yes, I'm still too lazy to polish it enough for publication (which includes writing tons of documentation), at least as of now, but I showed this latest incarnation to a friend lately, and he said I had to write something about it. Well, specifically how my object model is set up, because it's quite different from the normal way to deal with OO paradigms.

First of all, PHP is dynamic, and has some cool "magic" functions in the OO model which one can use for funky stuff. Instead of just extending the normal stuff with some extras I've gone and embraced it completely, and changed my programming paradigms and conventions at the same time. Let's just jump in with some example code;
// Check (and fetch) all users with a given email
$usercheck = $this->database->users->_find ( 'email', 'lucky@bingo.com' ) ;
Tables are are contextually defined in databases, so $this->database->users points directly to the 'users' table in the database. (Well, they're not really table names, but for this example it works that way) The framework checks all levels of granularity, and will always return FALSE or the part-object of which you want, so for example ;
// Get the domain of a users email address
$domain = $this->database->users->ajohanne->email->__after ( '@' ) ;
Again, it's like a tree-structure of data, a stream of granularity to get in and out of the data. This does require you to know the schema (and change the code if you change the schema), but apart from that, in a stable environment, this really is helpfull (it's also cached, so it's really fast, too).

You might also have noticed ... users->ajohanne->email .... Where did that "ajohanne" bit come from? Well, as things are designed, again the framework will try to find stuff that isn't already found, so "ajohanne" it will automatically look up in designated fields. All objects that extend the framework have two very important fields, one being the integer primary identifier, the second one the qualified unique name (so not a normal name as such, but a most often a computer generated one that isn't normally a number. Often systems will use things like a username, say, as a qualified name, and hence "ajohanne" was my username in one such system). Why do this?

Well, PHP is dynamic, so in my static example above, explicitly using 'ajohanne' as part of the query, isn't the best way to go in more flexible systems, but just pop your found user in dynamically instead;
$domain = $this->database->users->$username->email->__after ( '@' ) ;
Easy. And this applies to all parts of the tree, so this works as well ;
$domain = $this->database->$some_table->$some_id->$some_field->__after ( '@' ) ;
No, from the two examples above we might see a different pattern, too. All data parts has unrestrained names, all query operations use an underscore, and all string operations uses two underlines. (__after is a shortcut for substr ($str, strpos ( $str, $pattern ) ), and I've got a heap of little helpers like this built in ) Through this I always know what the type of the object interface is, and with PHP magic functions these types are easy to pull down and react to. As some of my objects are extendable, I need to pass _* and __* functionality up and down the object tree.

Traditionally, we use getters and setters ;
$u = $obj->getUsername() ;
$obj->setUsername ( $u ) ;
I turn them all into properties, so ;
$u = $obj->username ;
$obj->username = $u ;
But they are still full internal functions to the object, and this is another magic function in PHP ;
class obj extends xs_SimpleObject {
function getUsername () {
...
}
function setUsername ( $value ) {
...
}
}
The framework isn't just about object persistence. In fact, it is not about that. I hate ORMs in the sense that they still drag your OO applications back into the relational database stoneage with some sugar on top. In fact what I've done is to implement a TMRM model in a relational database layer, so it's a generic meta model (Topic Maps) driving that backend and not tables, table names, lookup tables, and all that mess. In fact, crazy as it sounds, there's only four tables in the whole darn thing. I'm relying on backend RDBM systems to be good at what they should be good at; clever indeces, and easier joins in a recursive environment (which, when all data is in the one table, it indeed is recursive), where systems use filters to derive joins instead of doing complex cross-operations (which takes lots of time and resources to pull off, and is the main bottleneck in pretty much any application ever created which has a database backend.

A long time ago I thought that the link between persistent URI's for identity management in Topic Maps and the URI (and using links as application state) in REST were made for eachother, and I wanted to try it out. In fact, that fact alone was the very inspiration for me to do the 3rd generation of xSiteable, hacking out code that basically has one URI for every part of the Topic Map, for every part of the TM API, and for other parts of your application. Here's some sample URIs ;
http://mysite.com/prospect/12
http://mysite.com/api/tm/topics/of_type:booking
http://mysite.com/admin/db/prospects
At each of these there are GET, PUT, POST and DELETE options, so when I create a new prospect, it's a POST to http://mysite.com/prospect or a direct PUT to http://mysite.com/prospect/[new_id], for example.

All in all, this means I have many ways into the system and its data, none of them more correct than the other as they all resolve to topics in the topic map. This lowers the need for error checking greatly, and the application is more like a huge proxy for a Topic Map with a REST interface. It's a cute and very effective way of doing it. I'm trying various scaling tests, and with the latest Topic Maps distribution protocols that I can use for distributing the map across any cluster, it's looking really sexy (although I still have some work to do in this area, but the basics rock!).

Anyway, there's a quick intro. I guess I should follow this up with some more coded details of examples. Yeah, maybe next week, as I need to get some other stuff done now, but I like the object model I've got in place, and it's so easy to work with without losing the need for complex stuff. Take care.

13 March 2009

And so a new era begins

Well, yeah, it would be easy to think my headline had anything to do with changing my life, move to the other side of the planet, new job under new circumstances doing new and kick-ass things (more on all this later), but no, this is about how I wanted to "just have a look" at something which buggered my computer up, and how it changed things for the better.

So, many eons ago, I was a Linux hacker. Well, not a true hacker, but I used to adminster a Red Hat box and create some custom programs in C++. Hmm, must have been, like, about 15 years ago, as part of my civil service (military service is mandatory in Norway, which didn't fit well with my non-violent ideals) which was at the same time I ventured into the Internet as well. So, a long, long time ago, in a place I'd rather just forget about, I fiddled and meddled in the dark arts of software computing. I've always stayed in contact with Linux, but my main OS from that time on has always been in various evil Windows incarnations.

Last week I bought a new computer, a slick Toshiba Satellite P300, that came with Windows Vista. Ugh. I had big reservations against Vista, but I was in a hurry, and thought to myself that surely, it can't be that bad, right?

Well, it was. Slow, sluggish, confusing, and I seemed to have little or no control over who went online to download anything they felt like. I thought, in a quiet moment while the internet connection was bogged down by the virus program or the updater or some other bloody download I couldn't figure out, that perhaps I should finally check out my good old friend, Linux, to see what he was up to these days. I went to the distro I know has got a good load of feedback, Ubuntu, downloaded an ISO (Gutsy Gibbon, 7.10) and burned myself a CD. I popped it in, and without thinking too clearly installed it using the automatic partitioning tool.

It's that tool that made a boo-boo of sorts, and managed to wreck my Windows install; I couldn't boot into it anymore, no matter how much I tried to fix it (I've got a bit of partitioning and formatting experience through the years, luckily). So I was more or less forced to have a deep look at it to see if it could do the things I need to do.

First, the whole install took no time at all. Vista felt like an eternity with multiple restarts (over 50 minutes on my laptop), Ubuntu just copied files over, did some juggeling, and one restart (about 20 minutes). Nice.

Secondly, the Gnome desktop environment is great. I installed some extra Compiz stuff as well, and I'm quite blown away with the options, effects and stuff you can do. The standard applications and tools is more than enough for most things, perhaps with the exception of something for all the web developers out there, but that brings me to the next point;

Installing Apache2, PHP5 and MySQL/SQLite was amazingly easy, even with the extensions I need, just "sudo apt-get" a few packages, and the rest is done for you. Locate the config files in /etc/apache2 and /etc/php5, and I was done in 5 minutes, including setting up a few projects that I work on that simply Just Worked (TM) straight out of the box. I was never able to get this right so fast on Windows, and yet here it was almost too easy. I'm very impressed.

Same with NetBeans, Ruby, Python, Firefox and extensions, it all just is find the file for the packager (based on the Debian packager) and the rest is easy. The selection of software is very good, and I've been using my system as a professional for a couple of weeks without a single hitch. It's found all my hardware as well, except perhaps my Lexmark 7600 series Wireless printer (which I haven't really seriously tried to install yet, only poked around) and some glitches with hibernate and suspend (but given the time it takes for this baby to properly close and boot up again, I'm not really saving much time trying to hibernate anyways).

All in all, my first impressions are really positive, and I'm glad I had an install glitch; I love my new Ubuntu, and I can't wait to get more serious about it and Linux again. I think I've made the permanent switch.