Making It Happen

A while ago, I had an idea for a cool website. It involved grouping blog posts under “debate” questions. There was a simple mechanism for auto-detection if you linked a blog post to a debate page. The point was to be able to group postings with more semantic richness than simple tags or categories.

It fell by the wayside, so I took it down after a few months. Recently I’ve been seeing sites pop up based on similar ideas. AllVoices is one, and Debategraph.org is another. It’s nice to see the idea of information richness continuing to develop in interesting ways.

And it makes me wish I had stuck with my site idea, though to be honest, it wasn’t realistically feasible. The hardest part wasn’t coding the functionality, which only took 2-3 weeks of the large pool of free time I had back then. (Side goals were to get a working knowledge of CherryPy and sqlalchemy, so at least those were accomplished!) No, the real difficulty was “selling” it to users: publicizing the site, making it visually attractive and user-friendly, and getting people to use it in their own blogs. I didn’t have the skills or resources to make those things happen.

There’s an adage that says success on the web largely depends upon execution, not the concept. That’s so true. I feel like I’ve known so many smart, talented technology people who excel at what they do but haven’t been able to pull off their interesting side projects. I think it’s because we often underestimate the non-technical challenges in getting a website off the ground. In many ways, those are more important to do well than solving the technological problems.

The oxymoron of perl best practices

I’ve been browsing Damien Conway’s excellent book, Perl Best Practices. His description of “best practices” in Chapter 1 is quite good, bestowing meaning upon an otherwise empty buzzword for marketing departments:

Rules, conventions, standards, and practices help programmers communicate and coordinate with one another. They provide a uniform and predictable framework for thinking about problems, and a common language for expressing solutions. This is especially critical in Perl, where the language itself is deliberately designed to offer many ways to accomplish the same task, and consequently supports many incompatible dialects in which to express any solution.

Simply put, best practices are the recognizably tried-and-true. The key word is recognizable: others should be able to identify the problem being solved as well as the specific type of solution. In a way, it’s redundant to speak of best practices when talking about the programming: unless no one will ever see your code, the foremost consideration of the programmer should be, Can other people understand what I’ve done easily and quickly, and also make changes and improvements easily and quickly?

That question is really at the heart of coding as a craft of logical elegance, I feel. Giving it due care and consideration is what distinguishes artisans from those who just “get it done” (they always seem to run into perpetual headaches down the line).

I find the philosophy of perl to be highly antithetical to the sort of shared understanding and communication described above. The motto of “there’s more than one way to do it” is self-serving and individualistic, to the detriment of maintainability. Perl seems to foster stubbornness and isolation: I’ll do things MY preferred way, and you do it YOURS. The codebase quickly devolves into baffling inconsistency. Of course, skilled perl programmers pride themselves on being able to know all the different ways of doing something, but at that point, the strength of the language isn’t the issue anymore; the ego of the coder is.

Anyway, back to Conway’s book. What’s interesting, but perhaps not surprising, is the number of “don’t do X” recommendations it makes. Leaving off parentheses on subroutine calls? Convenient, but ugly and confusing when a bunch are these are combined, so don’t do it. Tricks with dereferencing syntax? Save everyone headaches and stick to arrows. Pseudohashes? Stay away from them. Indirect object syntax? Potentially conflicts with subroutine names, so don’t use it.

Take away all the crazy tricks that perl devotees love, and what’s left? The only truly great thing about perl is its regular expression integration and text processing. It’s amazing stuff. But otherwise, perl doesn’t particularly excel at much else.

Which is not to say large complex projects in perl are impossible. The University of Washington’s Catalyst tools use a custom web framework written in perl, which they’ve open sourced. I only cite that particular example because I’ve used some of the tools and I know they’re nicely done. So sure, it’s possible, but it takes a lot of deliberate restraint and discipline, more so than with other languages and tools that are oriented towards helping you get your job done.

Seems to me that if you must willfully refrain from using what a language offers, and constantly fight the temptation to write mangled code that costs time, money, and frustration for others to decipher, perl isn’t a particularly strong choice. In the case of perl, best practices aren’t a way to get the most out of the language; they’re a stopgap measure to stave off its natural tendency towards chaos.

Eclipse and JDK 1.6.0_05 on Mac OS

Last week, Java 1.6 went out of Developer Preview and became an “official” release for Mac OS 10.5.2. (You still can’t get 1.6 for 10.5.1, sadly.) I’ve been fiddling with 1.6 and Eclipse, trying to get them to play well together, and here’s what I’ve found so far.

Eclipse itself needs to run on 1.5. There’s a great blog post, “Running Eclipse on MacBooks with Java 6”, written by one “rkischuk,” that explains why: 1.6 doesn’t support 32-bit SWT-Cocoa bindings, so Eclipse will bomb. The error I got was a mysterious “JVM Terminated. Exit code=-1” and a list of run-time options. If you run Eclipse from a shell, you might see this:

2008-05-09 10:53:55.443 eclipse[257:10b] Cannot find executable for CFBundle 0x116030 (not loaded)

or maybe this:

_NSJVMLoadLibrary: NSAddLibrary failed for /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Libraries/libjvm.dylib
JavaVM FATAL: Failed to load the jvm library.

When I installed 1.6, I had messed around with /System/Library/Frameworks/JavaVM.framework/Versions, trying to get 1.6 to run as the system default. But the cleanest solution for me was to KEEP 1.5 as the default. So make sure that directory looks like this:

drwxr-xr-x 11 root wheel 374 May 9 10:49 ..
lrwxr-xr-x 1 root wheel 5 May 5 22:41 1.3 -> 1.3.1
drwxr-xr-x 3 root wheel 102 Nov 2 2007 1.3.1
lrwxr-xr-x 1 root wheel 5 Apr 18 13:07 1.4 -> 1.4.2
lrwxr-xr-x 1 root wheel 3 May 5 22:41 1.4.1 -> 1.4
drwxr-xr-x 8 root wheel 272 Apr 27 2007 1.4.2
lrwxr-xr-x 1 root wheel 5 Apr 18 13:07 1.5 -> 1.5.0
drwxr-xr-x 8 root wheel 272 Apr 27 2007 1.5.0
lrwxr-xr-x 1 root wheel 5 May 5 22:41 1.6 -> 1.6.0
drwxr-xr-x 8 root wheel 272 Apr 18 14:03 1.6.0
drwxr-xr-x 9 root wheel 306 May 9 10:50 A
lrwxr-xr-x 1 root wheel 1 May 9 11:13 Current -> A
lrwxr-xr-x 1 root wheel 3 May 9 11:12 CurrentJDK -> 1.5

Eclipse should run as it normally does.

If your code project(s) don’t require SWT, you can use 1.6 as an Installed JRE within Eclipse. Go to Preferences -> Java -> Installed JREs -> Add…. Select “Mac OS VM” and point it to:

/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home

Building projects and running JBoss using the 1.6 seems to work just fine.

Lessons Learned

After about 5 months, I’ve decided that it’s time to move on to another gig. I’ve learned a few things, and I’m posting them here in the hopes that the lessons might be helpful to other programmers and techies-at-large.

Working in a small business as the sole do-it-all technology person has its unique challenges. It can be very fulfilling to be the sole expert and “enabler,” if that turns you on. But the flip side is that management might not really understand or care that much about their technology. Is there a reasonable budget for what they’re trying to accomplish? Do they understand, at a high level, your projects and how they contribute to the mission? Are technology projects considered a burdensome mystery or something valuable and embraced by the company? Question the reasons why there’s only one tech guy/girl and whether that seems right.

Another thing to assess is whether you can deal with taking over the existing codebase. I’ve taken over other code before with success, retaining what was good and doing clean up as necessary. At this past gig, things looked reasonably tidy at a first glance, but as time progressed, I realized a ton of abstractions weren’t in place, and those that did exist didn’t make sense. Some refactoring might have been interesting to do, but this endeavor wasn’t valued when I proposed it as a project.

Lastly, I think it’s important to be wary of promises about the future. Even with the best of intentions, things change quickly at small businesses. The projects I was initially excited about got perpetually deferred for various reasons, and I found myself preoccupied with doing maintenance code fixes, making cosmetic tweaks, performing server administration, and providing support for third party software (which I really don’t like to do). The company needed these things done, so I did them with as much cheer as I could muster, hoping we’d eventually get to a place where some solid new development could occur (and I could sneak in some refactoring)—that’s what floats my boat. But it became to clear to me that wasn’t going to happen anytime soon.

So that’s that. It’s a shame it didn’t work out, especially since I actually liked everyone I worked with. At least it’s an amicable departure, and I hope to be involved in hiring a replacement who might be a better fit for their current needs than I am.

The new gig? Java. Been catching up on it, since it’s been a few years. Oh, it feels so nice to have package namespaces, real data types, full-featured APIs, and real object-orientedness again. Like coming home.

The Small Business Subconscious

Small businesses can be challenging places to work. You often have to make do with few resources, play several roles at once, and be flexible enough to deal with loose/nonexistent company organization. If everything magically clicks, as it sometimes does, it can be a beautiful thing. But more often than not, that simply doesn’t happen.

As I talked about this with friends who have had similar experiences, they observed that there’s often a common mistake made in small businesses: since every employee is precious, the organization tries to extract as much value as possible by encouraging everyone to contribute in as many ways as possible. It bills itself as a democracy, as an environment that genuinely listens to its employees.

The problem, of course, is that when people aren’t in sync about the mission, or about specific project goals, you end up with a frustrating mess of conflicting directions. The business (somewhat desperately?) tries to latch onto everything at once, and there’s a lack of decisiveness in moving forward. Projects get fragmented. People believe they’re collaborating but they’re actually not. Confusion ensues. Little gets done.

Leadership is even more key in small businesses than in larger ones, I’d wager. Because if you have few resources, you need to choose your projects very carefully, dedicate resources accordingly, and make absolutely sure they go to completion quickly. There’s not much room for failure. But instead, small businesses seem prone to being wishy-washy. The insidious and tragic aspect of this is that when projects move at a snail’s pace or even fail, the accountability falls back on the individuals. Because management failed to lead, it can remain blame-free. It’s a formula for endless frustration.

In this unfortunate strategy, the small business is structured like the subconscious and its conflicts. Its desire is vague and repressed, and though seemingly absent, it’s actually very much the motive force for its existence. Like a human being, the small business can’t decide upon its identity, which remains in flux. And just like a human being, this repressed desire can lash out violently when it isn’t fulfilled.