The Myth of Artisanal Programming

Paul Chiusano, the author of the excellent Functional Programming in Scala from Manning (one of the few tech publishers I buy from; worth every penny), recently wrote a blog post titled, “The advantages of static typing, simply stated”.

Lately all I seem to do is rant to people about this exact topic. Paul’s post is way more succinct than anything I can write, so go over there and read it.

While he takes pains to give a balanced treatment of static vs dynamic type systems, it seems much more cut and dry to me. Dynamic languages are easier and faster for development when you’re getting started on a project, and it’s great if that project never gets very big. But they scale very poorly, for all the reasons he describes. Recently, I had the daunting task of reading almost ~10k lines of Perl code (pretty good Perl, in my opinion). It was hard to make sense of and figure out how to modify and extend, whereas the MUCH larger Java codebase (over 100k lines, if I recall) that I worked with years ago felt very manageable.

My own history as a programmer matches Paul’s very closely. I started with Java, which was annoying but not a bad language by any means. Then Python came along and seemed like a liberation from Java’s rigidity and verbosity. But Python, Ruby and others are showing their weaknesses, and it’s no mystery why people are turning to the newer generation of statically typed languages like Scala, Haskell, Go, etc.

People who haven’t been around as long don’t necessarily have this perspective.

In retrospect, it’s interesting to me how we programmers “got sold” on dynamic languages, from a cultural perspective. You might recall that a big selling point was using simple text editors rather than IDEs, and there was this sense that writing code this way made you closer to the software somehow. Java was corporate, while Python was hand-crafted. There was a vague implicit notion of “artisanal” programming in these circles.

The upshot, of course, is that every time you read a chunk of code or call a function or method, your brain has to do a lot of the work that a statically typed language would be able to enforce and verify for you. But in a dynamic language, you won’t know what happens until the code runs. In large measure, the quality of software hinges on how much you can tell, a priori, about code before it runs at all. In a dynamic world, anything can happen, and often does.

This is a nightmare, pure and simple. Much of the strong focus on writing automated tests is to basically make up for the lack of static typing.

True artisanship lies in design: namely, thinking hard about the data structures and code organization you’re committing to. It’s not about being able to take liberties that can result in things that make no sense to the machine and that can cause errors at runtime that could have been caught beforehand.

On Magic

Kids, I hate to break it to you, but there is no such thing as magic.

The cool whizzy stuff on your screen that impresses you: that’s the result of work. The button that was broken yesterday, that now works correctly today: also the product of work. The screen that was discussed in a meeting last week that suddenly appeared today on the development server: yup, work. When you look for a feature in the web application and it isn’t there, there’s this thing that can create it and put it there: it’s called work.

Someday we’ll all get over the mystifying aura of technology. Someday people will learn to recognize that programmers are not magicians, just workers, and that the work they do involves mundane, non-magical tasks, like wrestling with code libraries and frameworks to get them to do what we want, reorganizing files to make sure stuff exists in sensible places, and figuring out what to do when changing one piece affects three other pieces in unexpected ways.

And this means, someday, people will understand that, like any other kind of work, software development takes resources (namely, time!), not a magic wand. And no amount of “ambition” (read: wishful thinking) can really change that basic equation. You can pretend magic exists, but that doesn’t make it so. You aren’t fooling anyone. You just look childish.

When software development is recognized as work, there can be clarity about what is possible with a given set of resources. Then tasks can be sanely identified, specified, prioritized, coordinated, scheduled, executed, completed.

And then some really cool things can happen. Not magical things, but really cool things. Great things, even. The kind of great things that result from understanding, dedication, and hard work.

Goodbye Ubuntu, Hello Debian Testing

This past weekend, I finally made the switch: I replaced Ubuntu with Debian testing on my main computer.

I really dislike the direction that Ubuntu has been taking lately. Don’t get me wrong: from a technical standpoint, Ubuntu is a great distro, the first and only Linux I’ve used where every single thing Just Worked after installation (I’ve run Slackware and Debian in the past, and maybe one or two others I can’t remember just now). I liked that its releases did a good job of including very recent versions of software. Without a doubt, Ubuntu has done a LOT to put Linux within reach of a wider user base.

But it’s come at a cost. Ubuntu 12.04, which is what I used to run, has spyware. (Here’s a good page with instructions on how to remove it, as well as make other tweaks.) Even if you like Unity, it’s a huge resource hog. And it annoyed me the way Ubuntu’s app store was so similar to the package manager: it seemed designed to lure people into the app store unnecessarily. The shopping results in Dash and privacy concerns were the straws that broke the camel’s back.

I get that Canonical is a business whose ultimate goal is to make money. I wonder if a subscription fee model would have worked for them. I would have gladly paid a reasonable amount to get a quality, user-friendly, up-to-date distro.

So yeah, I’m now running Debian testing on my Toshiba Portege R835 laptop. I chose Debian testing mostly because a lot of packages in stable are a bit too old for my tastes. stable is a great choice for the server, but for my everyday machine, I wanted the latest and greatest, or the closest thing to it that’s still fairly dependable. Debian testing fit the bill.

The install process is not as easy as Ubuntu, but it was fairly painless and seems much improved from years ago. A few notes on what I did:

  • Since I wanted “testing”, I used the latest daily snapshot of the Debian Installer.
  • On the first screen, I chose the advanced options to selected Xfce as my desktop, so I wouldn’t have to uninstall gnome later and install Xfce manually.
  • When the install process finished and I rebooted, my wireless didn’t work. The wireless device in my laptop is a “Intel(R) Centrino(R) Wireless-N”, which requires an additional package with firmware to be installed. Run “apt-get install firmware-iwlwifi” as root to get it, and reboot.
  • I changed my /etc/apt/sources.list file to use “testing” instead of “jessie” so that I would always be tracking the rolling testing release.
  • Getting Flash to work in the browser requires adding the “nonfree” section to the apt sources, and installing the “flashplugin-nonfree” package.

That’s it! Suspending my laptop works just fine, and connecting usb drives and devices works without any additional setup (which was not the case the last time I used Debian many years ago!). So far, all my applications have been working seamlessly with the old data I copied over.

I like having the peace of mind that Debian would never install spyware or intentionally compromise users’ privacy. Yes, it was just a bit more work to install, and getting non-free software that I unfortunately need to use for work is a bit of a hassle, and there will probably be small configuration annoyances in the future that make it less “magical” than Ubuntu. But I’m willing to deal with that.

I hope to replace Ubuntu with Debian testing on my desktop machine at work too sometime in the next few weeks. So long, Ubuntu, it’s been nice.

On Reading Blogs and News Sites About Coding

My newsreader currently contains 60 feeds from blogs and news sites that cover programming and technology. There are some weeks where I refresh these feeds several times a day, combing through them carefully. And there are periods when I ignore them completely because I’m occupied with other things in life.

I’ve discovered a pattern. When I scour the feeds frequently, the information I learn doesn’t tend to help me all that much with my work or non-work projects. Once in a while I will learn about a useful library, or some programming language feature I didn’t know about before. But mostly, what happens is that I end up feeling anxious, like I am not productive enough. Just as Facebook connects us all while making us lonelier, discussions about coding on the Interwebs make me a bit smarter while also paralyzing me to the point of not being able to use that knowledge.

For all that I complain about technology (and I complain a lot), I do love coding. Becoming a more seasoned (I do not say “good”) programmer, for me, means learning the different ways of thinking embedded in various languages and tools: that is, understanding what makes something powerful and expressive, and what, in that same thing, makes it limiting. You create worlds when you write code, and these are fun and interesting to inhabit, to understand, to make grow.

Reading blogs and news sites usually doesn’t make love coding more, but less. Egomaniacal jerks abound. There is so much fluff in the latest trends. Even halfway decent web content is usually driven by shameless self-promotion. Github, as revolutionary as it is, sometimes feels like the Facebook of coding culture, a way to show off rather than genuinely collaborate. And don’t even get me started on ridiculous sites like Hacker News, where Silicon Valley is the promised land and every founder of a silly startup is Jesus. (Although if we could crucify them…)

All of this fuels a culture where people focus on one-upping one another, where the pace of change is so fast you are always playing catch up, where hyper-productivity overshadows questions about what that productivity is for…

These days I skim my tech feeds no more than once a week. My time is just better spent in other ways, like actually solving problems in the code I’m working on, instead of reading about the trendiest or most marketable ways to do it. There’s good knowledge out there, but it’s far and few between, and everything else damages rather than nurtures The Love.

Exercise Mania

My ex-girlfriend’s mom started doing a jazzercise class in the 80s and hasn’t stopped since. It’s a weird thing.

Programming exercises can be just as addictive as some forms of well-marketed physical exercise. I have to actively resist writing solutions in Lisp to every silly problem I stumble upon online. But this morning, I came across this simple one (a blog post from 2007, but that happens on Hacker News) and, for some reason, couldn’t pass it up:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

It’s so silly that I guess some folks, like the blogger linked above, have turned it into a problem of “what’s the most creative/strange way I can think of to do this?” Which is interesting and fun in its own right.

What I don’t understand is the attitude expressed in the original fizzbuzz blog post, “Using FizzBuzz to Find Developers who Grok Coding”. Does it really matter if it takes someone 5 or 20 minutes to write a solution? (FWIW, I took about 10 mins). A shorter time with such a goofy example means someone “groks” coding more than another? Ridiculous.

These types of puzzles are amusing precisely because a lot of real-world development (which is what the vast majority of people who code for a living do) is unfortunately pretty rote, and doesn’t require a lot of algorithmic thinking. Code monkeys learn to use libraries and frameworks, and spend a lot of time trying to use them correctly and cleanly, in order to implement straightforward requirements. So these exercises are a shift in mindset. In a tiny way, they put you back on the path of engineering. It’s why people find them interesting to do. It’s why I’m reading the Structure and Interpretation of Computer Programs.

Taking a few more minutes might mean you’re not accustomed to solving such problems every minute of your working life. But that’s not at all the same as gauging whether someone understands coding or not. That kind of measurement is naive at best.