« Archives in February, 2009

Lesson 4: Have a learning plan

This should go without saying, but it’s surprising how long I went without actually doing it.

A few years ago, I read Code Complete, which I’ve talked about at length here before. One of the first things that impressed me about that book was that it laid out a very precise reading plan that all newcomers to McConnell’ company had to follow.

Until that point, I’d mostly picked up new books and tried new techniques whenever I felt like it. If I heard of some reference or thought of some activity that would be beneficial to my learning (e.g. reading book X, or doing programming exercise Y) I would jot it down in a looong to-do list, and hope to get to it eventually.

After I saw McConnell’s suggested reading list, I went back to my own bucket of learning items and loosely organized them into a sequence. I also defined what it would take to actually get the desired benefit out of each activity. For books, this meant anything from skimming the text to doing all of the exercises contained therein. For extended exercises or activities, I gave a bit of thought to the scope that would be required to actually learn anything from the attempt.

This has ultimately resulted in me getting more out of the time I spend learning about my craft. For example, I’d previously read the Structure and Interpretation of Computer Programs. It only took me a week, but I’d be hard-pressed to tell you anything about the last four chapters of the book.

I then read it again, about a year later. This time it took me significantly longer to finish, but I hadn’t retained much of it. I decided that, in order for this activity to be worthwhile, I’d have to do a significant portion of the exercises in the book.

So now I’ve been working on SICP for about a year, and I’m not even halfway done the work I believe I will have to do in order to consider myself done with it. Yes, that’s a very long time. But, the value I get from each session is much higher than it would be if I was just skimming the same material. That is, every time I sit down with SICP and a stack of paper, I come away an hour or two later feeling a whole lot wiser than when I sat down.

I feel that the few hours that it took me to organize my list of “things I’d like to learn about” into a loosely annotated and ordered plan has helped me a lot. Hopefully it might help you as well.

Lesson 3: Think beyond OO

When your average software developer goes to break a subsystem or module into implementable pieces, generally her first instinct is to think “What are the classes and behaviours in my problem domain?” Whether you’re driving this design with TDD, or taking a more top-down approach, this question tends to be the linchpin of the design.

This is unsurprising. Object-orientation is (ostensibly) taught to most of us in school as the one-true-way of doing things. It’s rare to find people who do not equivocate software-design-in-the-small to object-oriented design.

A couple of years ago, I decided that I wanted to learn “functional programming”. My first serious attempt was in OCaml. However, once the wheels hit the ground, I felt like I had returned to highschool. At that time, I knew the syntax and vocabulary surrounding objects, but I had no idea how I was supposed to use them.

So, I reasoned, I needed to learn how to design functional programs. I needed to learn “functional design”, for lack of a better term.

After a bit of consideration, I remembered that there are a lot of very famous universities that teach the basics of program design using Scheme. (This is also true for OCaml, but the Scheme ones are arguably more famous :D .) This was perfect — I needed to learn how to design programs all over again, in a “functional style”. So, why not go back to basics? And thus did I seek out MIT’s CS1 old-style curriculum and the Wizard Book — also known as The Structure and Interpretation of Computer Programs (SICP). (They’ve since switched to Python, I think. I imagine the spirit is the same.)

You may notice that I’ve been putting “functional design” and “functional style” in quotations. The reason for this is that I quickly discovered that such things do not actually exist.

Let me explain.

The fundamental exploration that jumped out at me in SICP was this: Let’s say you have a programming model that supports first-class functions, and does a pretty good job of supporting immutable data. What reasonable methods of designing and implementing programs can we arrive at using this model?

And the answers are legion. A program can be viewed as a mathematical function. It can be viewed as a signal-processing device over finite sequences of discrete signal elements. It can be viewed as a signal-processing device over infinite sequences of discrete signal elements. It can be viewed as a processor of a domain-specific language. And so on.

What SICP really shows you is a variety of methods that you can use to design programs-in-the-small, with object orientation being only one of them. So now, when I’m working on a new chunk of some big project, I find myself thinking not “where are the objects”, but instead “what happens if I view this problem as, say, a signal processing problem?” Even more importantly, when I read someone else’s code, I can ask myself the same thing.

The reflex of explicitly asking myself this question when faced with a new design problem really helps to understand it from multiple angles, and to identify the things that are going to be the hardest to model or extend in any feasible design. And that lets me focus on clearing up the things that matter.

I won’t pretend to be a master of any design-in-the-small methodology. However, I’m now aware of a whole set of possibilities that I was once largely ignorant of, and this knowledge helps me in a bunch of little ways every day.