Archive for February, 2007

How much Design is Enough?

February 16, 2007

A Quick Comparison

Paul Graham. James Gosling. Whether you like the languages these guys champion or not, I think most people would agree that they’re both pretty good programmers. They also represent two different ends of the programming spectrum. Take the topic of program design, for instance; and by design, I mean spending time thinking about how to write a program before you actually write it. When asked what makes some programmers more productive than others, Gosling responded:

“They think about what they do. They don’t rush in and slap things together. They have a holistic picture of what is to be built.”

Seems like the kind of guy who would be a proponent of designing a program before you start writing it, right? Now, let’s look at what Paul Graham has to say on the subject:

“I was taught in college that one ought to figure out a program completely on paper before even going near a computer. I found that I did not program this way. I found that I liked to program sitting in front of a computer, not a piece of paper.”

So, on the one hand, we have the corporate Java programmers who like to work out every detail of a program before they start writing it, and on the other, we have the cowboy Lisp hackers who throw out code and hope for the best. Who’s right?

“We need our design methodologies!”

Allow me to start by saying that I lean more to Gosling’s side. Design is great. I’m wishing I had done more of it sooner.

For example, I’m currently working on a small strategy game. If I hadn’t taken the time to get an idea of how I wanted to write it first, I’d be screwed right around this point. My first problem came in how I wanted to represent the board. Should I just draw sprites in random locations? Should I store the board as a grid of tiles? Ultimately, I went with the tiles. At that point, I had a new problem: in addition to possibly holding a soldier, each tile would also have to have information about its terrain (mountain, forest, etc.).

How would I represent this information? Should I make a list for tiles, have each spot of the list hold an object of Soldier, and have each type of terrain I want derive from Soldier? That’s a bit messy. Should I hard-code terrain information based on the map I load? No, what if terrain changes during battle? If I hadn’t worked out these problems in the beginning, I’d have a mass of broken code.

There’s no need to go overboard on design. Before I started to write my game, I got a good idea of all the features the game would have, what classes and functions I would use in the program, and what all these elements did and how they communicated with each other. That’s all; it was really a very high level overview. But I’m glad I did it; you have to do some design.

Rebuttal from the Lisp Camp

The general sentiment among Lisp programmers who think they don’t need to do design is that the Lisp language gives them this freedom. I don’t really understand the logic behind this, but you can read any of Paul Graham’s essays, or a post on comp.lang.lisp, to find it.

No matter what language you code in, you have to do some amount of design; even in Lisp. When I was writing my RPG language in Lisp, I had trouble in the beginning because I was starting off with a bad design.

My original plan was to read words from a file and look them up in a symbol table to see how the rest of the line would be read. Eventually, I decided to represent rooms in the game as hierarchical data, like XML; I also decided to work backwards, and write the functions to process this data before I worried about constructing it from a file. Seems like a design decision, doesn’t it? If I had thought about my design before I began writing my program, I would have saved myself quite a bit of time.

To Be Continued…

This should probably be called “How much Design is Enough, Part 1”. This game is the first project I’ve ever done any real design on, and I’m very early in the coding process, so I’m going to have to see how it pans out. But so far, this design thing looks like it might be pretty cool. You should do it.

Now, I’ll wait for the angry comments to roll in.

Advertisements

Why it’s so Hard for Imperative Programmers to Learn Functional Languages

February 14, 2007

I’m not currently using any functional languages like Haskell and Lisp, but I’m certainly comfortable with them. I’m certainly no Haskell guru, but I’m good enough to use higher-order functions, ADTs, monads, etc. While I have a good grasp of functional programming concepts now, I had to travel a long, hard road to get to this point.

Picture if you will a programmer with a C-family background discovering Haskell for the first time. He’s heard some smart people talk about how cool it is, and it says right there on haskell.org that it will substantially boost your productivity, so he momentarily puts down his Java Enterprise Web Framework With a Really Long Name and starts reading a Haskell tutorial.

At first, everything goes well. He’s impressed by the fact that you don’t have to constantly compile code to see the effects of your program. But after using the REPL as a calculator for a few minutes, he decides to check out how you write Hello World. This is where things start going downhill.

He notices that the chapter on I/O is tucked away in the Advanced section. Curiously, he flips to it and discovers, not an explanation of console and file I/O, but a disscussion of type classes, monads, and the like. He wonders if everything will make more sense if he just visits the appropriate chapters, but no luck; Haskell looks like one big incomprehensible mess. Our imperative programmer goes back to his Java Enterprise Framework, and that is the end of that.

It’s very difficult for a programmer used to imperative programming to find a good Haskell tutorial, or a good tutorial on any other functional language for that matter. It’s not that they explain Haskell badly; many of them explain it rather well. It’s just that they explain the wrong parts of Haskell. Procedural programmers are more often interested in how to do I/O and create GUIs rather than in how to use Parsec or write monads.

This is one of the major barriers to adoption of the more esoteric languages; lack of learning material for “normal people”. To rectify this, I thought about how I would write a Haskell tutorial.

I figured I would start off with a discussion about how to use the REPL to develop simple functions, and to test programs. From there, we would talk about how functions are side-effect free. We might take a detour into recursion, and then go on to topics such as monads and type classes. It would just be a Really Good Tutorial.

Then I realized something: in this great tutorial of mine, there were no sections on how to do I/O. There wasn’t even a Hello World program. Therein lies the problem.

The only people who can write a Haskell tutorial are the people who know Haskell. Ironically, someone who knows Haskell won’t be able to write a tutorial for the average programmer. They’ll focus too much on the features that make Haskell cool, rather than how to do practical things with it; which is just what the average programmer wants. Haskell gurus have spent so much time in their theoretical wonderlands, they’ve forgotten what it’s like to be an outsider.

We really need a Haskell, or Lisp, or ML tutorial aimed at the rest of the world, not just at functional gurus. Although I’m certainly not going to write it; I’ve got my own projects to worry about.