Friday, April 16, 2010

In code, a rose by any other name smells less sweet

I regularly get jibed by coworkers for having naming discussions. When my daughter was hanging out at the office the other day and sitting in the back of one of my meetings, she snorted trying not to laugh as we kept going back and forth on how to name something. Just yesterday someone forwarded me Juliet's quote "What's in a name? A rose by any other name would smell as sweet." Very true, very true.

But in code, there is a lot in a name. A different name does not smell as sweet.

The name you give something has a lot of power. In many spiritual traditions, great importance is given to words. Kashmir Shaivism holds that the world is created through the power inherent in syllables and words - matrika shakti. Syllables actually concentrate the universal energy and create form, like vibrations of sound forming shapes in water or grains of sand.

I find this to be particularly true in code. The name you give something gives it a certain power. If you name it well, the role and intent of the class becomes crystal clear. It helps you refine what the class is doing, and strip away what it shouldn't be doing. If it is poorly named, often the code in the class is unclear in its design and role as well.

A great example of fuzzy naming is the famous "Utils" class. You might as well call this class "DumpingGround" because that's what it becomes. Same regularly goes for FooManager, FooHelper, and so on. It doesn't give any real idea what it's for, so it becomes a "whatever" class. Hm, I have a method I want to write, and I don't really know how it fits into the overall design, but hey, here is this Utils class, I'll just use that!

Names also become short-hand for well understood design patterns. If you name something FooBuilder, FooProxy, FooObserver, and so on, then readers expect it to generally follow the pattern. Misusing these well-understood suffixes is asking for trouble.

I often find myself renaming classes over and over again as I work on a piece of code. Each time it helps me refine my understanding. It's like the class and its role in life is slowly taking form out of the primordial ooze, until it stands there clear and strong, with a well-defined shape and purpose.

So laugh and snort all you want, ye plebians. Shakespeare wrote beautiful, beautiful prose, and I am sure he took great care to find the right words. He even invented many words we continue to use to this day. To me writing good, clear code is like the craft of prose - there is a lot to a name, and finding the right name is both an effort and a joy.

Friday, April 09, 2010

Deploying a Google Web Toolkit app to CouchDB using couchapp

I've been working on a side project using Google Web Toolkit (GWT), and I'm using CouchDB as the backend store.

There is a project called couchapp which makes it very easy to write an HTML/Javascript-only application (you know, the new cewl way to build apps), and store it directly in CouchDB.

Huh? What are the benefits of doing this?

Well, offline support is the big one for me. If I install a CouchDB instance on my local machine, and then set up replication, my app and its data can automatically be replicated to my local CouchDB. I lose my connection, that's fine, everything I need is there. I get back online, my changes are automatically replicated back to my CouchDB in the cloud.

It also makes it easy to share apps - just publish to a common 'app hub' and anyone who wants to can subscribe and get the app. If you're feeling kumbaya, your app can be read/write, so that app users not only modify the content, they can also modify your app itself and replicate your changes back up.

One more thing: with my app deployed to CouchDB, I don't need to write server-side code. None. No PHP, servlets, JAXB, XML, MySQL, blah blah blah. I can directly access CouchDB (and other web services like Facebook, Twitter, etc.) from my client-side JavaScript. To me that's a much simpler, cleaner environment.

But the thing is, couchapp by itself just supports HTML, JavaScript, and attachments. After much soul searching and feeling un-hip, I have finally come to terms with the fact that I am comfortable and happy in Java. I could learn JavaScript, but I think and breathe Java, it's what comes naturally to my fingers. But Java isn't native to the browser, and that's not the way the wind is blowing. So recently I took another look at Google Web Toolkit, and I liked what I found:
  • Dynamic client-side browser-native apps without having to write a lot of HTML/Javascript. Yeah, I like that.
  • Work in Eclipse, a comfortable place for me to be
  • Excellent integration with CSS, allowing easy styling of widgets by applying style settings your GWT Java widgets
  • Static typing. I actually like that, I have much more confidence that when I run it works.
  • Very easy code/run/debug cycle, in Eclipse
  • No need to deploy, just refresh your browser and your new changes are in
  • Excellent support for AJAX-style HTTP requests
  • Lots of widgets, and some very cool libraries, including a visualization library
  • Open source under a flexible license
  • Strong community
Basically, in the GWT world, JavaScript is like your bytecode - you really don't need to look at it and in general you don't care. As with 'asm' in C, you can 'drop into JavaScript' if you need to, but really that can be kept to a minimum. I highly recommend doing the tutorial, it's one of the best I've worked with in a while.
    So, what do couchapp and GWT have to do with each other?

    Well, it turns out it's pretty darn easy to drop a GWT app into the couchapp framework, press 'couchapp push', and voila, your GWT app is deployed to a CouchDB instance.

    Take a look at the GWT StockWatcher tutorial app running out of CouchDB on cloudant. Add some pretend symbols and it simulates random fluctuations in stock price. This was all written in Java, compiled down to JavaScript, and then deployed to a CouchDB instance on cloudant with a simple one line command...

    So, here's all you need to do:
    • Get couchapp (on Linux or Mac you should be able to do sudo easy_install -U couchapp)
    • Run couchapp generate myapp to generate a directory structure for your app.
    • Remove everything under myapp/_attachments. You can keep the views if you want, or remove them.
    • Get GWT (preferably the plugin for Eclipse)
    • Create a GWT project
    • When you're done testing/debugging locally, compile your GWT project for deployment
    • Copy everything under the 'war' directory except WEB-INF to the _attachments directory of your couchapp application directory
    • Run couchapp push (set up your .couchapprc first with the right settings)
    • Go to the URL provided by couchapp push and you should see your app running beautifully