English as Code as Pseudocode
(by Erik Peterson on June 28th 2008)

The Tradition of Pseudocode

Traditionally, when developers got together to talk about code, they would invariably end up writing pseudocode on the nearest white board, piece of paper or dinner napkin. The reasons for this are myriad. First, developers favor different languages, and might not be able to read their friend's favorite language. Especially 15 or 20 years ago, languages used to be so stylistically different that a developer who hadn't already had exposure to, say, Algol or Fortran, might not be able to easily parse even basic code statements. The second main reason for the use of pseudo code is that 20 years ago, most languages didn't read like English. If you wanted to really describe how a program worked, you would have to use pseudocode, because all of the programming languages you knew read like shit.

That's not such a big deal these days, also for a couple of reasons. First, the languages currently in favor are much more high level and all have much more sophisticated Object models than the ones of yore. You generally don't have to explicitly allocate memory, declare variables, or do other kinds of tedious dreck. With more refined OOP concepts, you (generally) don't have to write as much boilerplate or worry about dumb gotchas as you had to with antiquated object models like Java or Perl's sad excuse for OO. Secondly, most newer languages have gone a long way towards actually reading like English. Ruby and Python, in particular, have both eschewed the use of unnecessary tokens (braces in particular) and made their calling syntax much more natural.

As a result, you don't see much pseudocode being written these days. It used to be that anytime you would talk about algorithms, you would use pseudocode. Now? not so much.

Taking it a bit Further

So, since modern languages read so well that they have essentially supplanted pseudocode, should we stop there? Is it good enough that a programming language can be readily understood by any novice? I say no. I think we shouldn't stop pressing the development of languages until the concepts that the code is portraying cannot be expressed any clearer or more succinctly than they already are. That seems like a pretty hefty goal- to have a programming language that expresses things so clearly and succinctly that there is literally no room for improvement. We've generally seen the succinct side maximized- I would argue that Perl takes the cake on that one, and it is unlikely that there will ever be a language as succinct as it is. But Perl focused on succinctness at the expense of clarity. That's not really necessary.

So our goal is maximum succinctness and clarity. How far away are we? Surprisingly, not as far away as I had thought. Certain things have already hit this "wall of awesomeness"- domain-specific languages in particular. This following code snippet of the Rails plugin acts_as_state_machine does a great job of explaining both why I love DSLs so much, and why they're our best hope for accomplishing our goals:

acts_as_state_machine :initial => :pending
state :pending
state :submitted

event :submit do
  transitions :from => :pending, :to => :submitted
end

Try reading that code. Literally read it. It should read something like: "This acts as a state machine, with an initial state of 'Pending'. It has two states: 'Pending' and 'Submitted'. It has an event called 'submit' which transitions from pending to submitted." You'll notice something about reading that- the code is actually more clear and more succinct than the English representation of the code. Drawing a diagram of this small state machine would take longer and possibly be less clear than the code sample itself. When code is both clearer and shorter than either English or a drawing, you know you've won.

Are We There Yet? Are We There Yet? No!

That one example explains why I'm such a big fan of Ruby. It encourages code to both read like English and to read better than English. Whenever I come across a common pattern in my code, I find it extremely easy to abstract out that pattern into a DSL and bask in the clarity. This usually achievable, but isn't always easy, as in this example:

needs_approval do
  of department.manager
  of User.cfo if total_price > 5000
end

This code comes from a plugin that I was working on when I originally published this article. This code specifically deals with an approval structure for a Purchase Order. Each purchase order needs the approval of the Department Manager and, if the total price of the PO is over $5000, the CFO. This is actually pretty good.

I updated this article on July 17th, after I released the plugin. I was able to figure out a way to clean up the syntax quite a bit, and remove all of the brackets. I thought that I needed Ruby to have more power (specifically, being able to pass blocks around willy-nilly), but really I just needed to work hardt to create some nice syntax. So are we there yet? Maybe. I might be.