Composition and Inheritance

For as long as I can remember, writing any kind of non-trivial software meant you needed to use object-oriented programming. It was a no-brainer. So I learned all the fundamentals of OOP, and design patterns as well, since one couldn’t get very far in Java without knowing the most common patterns.

I think taking OOP for granted as the only natural way to manage complexity is why learning Lisp is so mind-blowing for programmers like myself. Take, for example, polymorphism. I didn’t know that there was anything besides parametric polymorphism–and I didn’t know it was called that; I knew it only as polymorphism, plain and simple. The ability of Lisp to do multiple dispatch was incredibly eye-opening.

I think this is the sort of thing people mean when they go on about how Lisp has broadened their horizons and deepened their understanding of concepts.

To mention another example, in a bit more detail: as an experiment in some recent python code for work, I’ve been using fewer classes/objects and more functions. (It’s debatable just how much actual “functional programming” mileage you can get out of Python, but I’ll put that aside for now.) In such an approach, you inevitably end up using a lot of composition, rather than object inheritance, to build higher level abstractions. And that’s been working out very well so far.

Composition is a powerful thing because you can control the granularity of code reuse. With a carefully constructed library of functions, you can choose to call the functions at the appropriate level of abstraction you need, and even mix and match. That’s much harder to do with object inheritance, where classes force you into an all-or-nothing package deal–if you want only some of the functionality, you need to instantiate the whole object anyway. And if you want to selectively override functionality, you need to subclass, which effectively ties the parent class to its subtree, making it harder to modify in the future.

I’ve been thinking lately that objects are useful mostly to facilitate data abstraction: there’s no reason not to group together related accessors and mutators. But when I consider more complex bundles of functionality, I think twice before creating a class hierarchy and see if I can do it using functional composition instead.

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.

An SICP exercise in implementing cons, car, and cdr

I started working my way through the Structure and Interpretation of Computer Programs this week.

Contemporary “intro to programming concepts” texts tend to focus on real-world examples in areas like business and web-based applications. In contrast, SICP involves a lot of math problems. I’m liking this about the book. Math is particularly good for illustrating the difference between declarative and imperative knowledge, between “describing properties of things and describing how to do things.” You may know, formally, what a square root is, but coming up with a procedure for calculating the square root of a number is another matter. Bridging these two kinds of knowledge is the essence of what computer programming is about.

The second section, “Building Abstractions with Data,” starts by discussing different ways to implement an abstraction for rational numbers. The text walks through using a Lisp cons cell to store a numerator and denominator pair, and using car and cdr as selectors. Then it provides this exercise, which I found particularly intriguing:

Exercise 2.5. Show that we can represent pairs of nonnegative integers using only numbers and arithmetic operations if we represent the pair a and b as the integer that is the product 2a3b. Give the corresponding definitions of the procedures cons, car, and cdr.

That’s a really clever way to store a pair! But perhaps I only think so because I’m not a math person.

At any rate, I wrote a solution in Common Lisp, with some helper lambdas to calculate log and pow arithmetically.

I’m finding that thinking about math problems and learning Lisp are helping me think more algorithmically about solving problems in the code I write for work. Maybe I’m starting to experience what Eric S Raymond famously wrote about Lisp: that it “will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.” I’m holding out hope for that last part though…

SBCL 1.0.55 x64 needs GLIBC 2.14

It installed on my Ubuntu 11.10 (Oneiric) laptop, but when I tried to run it, I got this message:

sbcl: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by sbcl)

Hmmm. Let’s see..

# ls -al /lib/x86_64-linux-gnu/libc.so.6
lrwxrwxrwx 1 root root 12 2012-03-06 21:17 /lib/x86_64-linux-gnu/libc.so.6 -> libc-2.13.so

Argh.

This has already been reported in the SBCL bug database.

My workaround was to grab 1.0.54 from the old file releases section on SBCL’s sourceforge site. That worked fine. So you’ll need to downgrade if you want to use the 64 bit version.

This came up when I ran into problems installing cl-libxml2 using quicklisp. The x86 version of SBCL throws an error when using cffi to load the Ubuntu-packaged libxml2 library, because it expects a 32-bit version of the library but finds a 64-bit one instead (I neglected to copy the error message, but it’s something about finding an unexpected/wrong class ELFCLASS64).

So I suspect anyone who has a x64 system that uses cffi to access libraries in this manner will run into the same problem with SBCL 1.0.55.

On a side note, I can’t imagine installing and managing Common Lisp libraries without quicklisp. It took a few seconds to do what would probably take a beginner like me hours to figure out. Awesome tools like that make a huge difference to newcomers who want to get up and running with CL without a lot of pain.

* * *

UPDATE: This is fixed in 1.0.56.

Unity sucks at the one thing I need most from a desktop environment

A few weeks ago, I switched from Ubuntu’s default Unity desktop to Xfce.

Why? Because hitting Alt-Tab to cycle through windows takes about a 1/4 sec for Unity to register. I cycle through windows literally hundreds of times a day. And that small but perceptible pause was driving me completely bonkers. Mind you, this is on my brand spanking new Core i5 laptop. Unacceptable!

What good are all the cute visual effects, glowing icons, and retracting launcher bars if Unity can’t smoothly perform the ONE function that defines what a desktop environment is supposed to be for: managing my application windows?!

In Xfce, Alt-Tab responds immediately.

There is also the small plus that the laptop battery seems to last a bit longer running Xfce than Unity. It’s not perfect, of course. Switching to and from an external display causes some issues. And I’d like a better volume control widget in the panel. But to me, these are minor annoyances.