lördag, mars 29, 2008

Meta-level thinking

I have been trying to figure out what characterizes some of the best programmers I know, or know about. It's a frustrating endeavor of course, since most of these people are very different from each other, and have different experiences and ways to think and learn about stuff. Not to mention the fact that programmers tend to be highly individualistic.

But I think that I'm finally zeroing in on something that is general enough but also specific enough to categorize most of these people, and the general mind needed to be a really good programmer. In this blog post I'll call that "meta-level thinking", and I'll explain more about what I mean as we go along.

When people try to become better programmers there are generally a few different kinds of advices you can get. The ones that seem prevalent right now is (among others):

  • Learn - and understand - Lisp
  • More generally, learn a new language that is sufficiently different from your current knowledge
  • Work with domain specific languages
  • Understand metaprogramming
  • Read up on the available data structures (Knuth anyone)?
  • Implement a compiler and runtime system for a language
Of course, these are only a few examples, and the categories are a bit fuzzy. These items are based on most of my experiences so they tend to be a bit language heavy. But I believe that what you practice by choosing any of these routes is an ability to abstract your thinking. In short, I believe that being able to abstract and understand what goes on in a programming language is one way to become more proficient in that language, but not only that - by changing your thinking to see this part of your environment you generally end up programming differently in all languages.

This is why Lisp has a tendency to change the way people write Java code. Lisp teaches you metaprogramming and DSL's but they don't really do it in a way that need words. DSLs and metaprogramming are just part of Lisp. It's so much a part of the structure that you don't see it. But when you turn to Java you'll need to start working with these abstractions on a different level. Ruby programmers embrace metaprogramming and this changes the way these Ruby programmers think about things.

I'm really happy to see metaprogramming and DSLs getting more and more focus, because I really believe that understanding them is a really good way to make programmers better. Of course, you can get the same effect by writing a copmiler and runtime system - as Steve Yegge proposes. But I disagree that you really need that experience. There are other ways you can get the same way of looking at the world.

I call this meta-level thinking. I think it's mostly a learned ability, but also that there is an aptitude component. Some of the best programmers I've met just have a mind that fits very well. It's interesting to note that this kind of meta-level thinking is not an ability that is only applicable to programming. In fact, that's probably just a matter of genetic luck that the same ability works very well for programming as for many other things. I think that there is a connection between certain abilities and a capacity for meta-level thinking too. Like music - it's interesting to see how many programmers that have artistic leanings, and specifically towards music. It would be interesting to see some statistics about this.

In conclusion, this is my somewhat fuzzy view about what is one of the most important abilities that contributes to create brilliant programmers. If you have any interesting ideas about other ways you can reliably practice this ability, please improve on my list.

10 kommentarer:

Anonym sa...

I think it's about abstractions. That's what programmers have learnt to work with, and what a good programmer has mastered. Languages like Lisp or Haskell enable the expression of a large set of abstractions, and in effect offer more opportunity to learn about them.

Andreas

Mats Henricson sa...

I'm sorry, but I can't see any fit between your observations and mine. I consider myself a fair programmer, but the difference between me and my great co-worker (hi, Janne) has nothing to do with "meta-level thinking". It has much more to do with a fierce drive to never ever accept sloppy design or code. He will never accept increased technical debt, unless there is a true panic going on.

When thinking about some other great programmers I've encountered over the years, such as Lars, Per, Steve and Stephen, what perhaps connects them all is a will to never buckle under pressure. They know how to produce great code, and will not stray away from their known paths even when pressured.

Anonym sa...

I think abstractions and meta-programming is nice, but sometimes you cant abstract, especially not on a lower level if you depend on a specific OS.

To create a directory you cant abstract much, at least it would not make much sense to abstract that.

I think if the underlying OS however supports more abstraction in theory (Plan9) you could go a different route.

My point here is that meta-programming, abstractions etc... all live better if they are in and on an ecosystem that supports these notions.

This is why I believe UNIX is very practical but not a genious concept. Its rather stupid :/ and I hope that in the future we will see much more interesting AND better abstractions of how to work with an OS. (My favourite example - look at the GUI world on UNIX. It still struggles! But look at the www, with beautiful javascript events onClick etc... that is a somewhat nice abstraction - although I agree that the www itself has became rather complex and obfuscated, with so many people relying on XML ...)

Unknown sa...

Anonym: I think the point is that meta-level thinking allows you to easily create new abstractions that better fit the program you're trying to write.

Twylite sa...

Laziness, impatience, hubris.

http://www.netropolis.org/hash/perl/virtue.html

A good programmer will find the simplest, most efficient and (by extension) most elegant solution ... even if it means researching, investigating and learning to come up with it.

One could say that a good programmer tries to minimize effort, but doesn't count research and learning as effort.

Fredrik Wendt sa...

On the comparison to being musically skilled, or artistically leaned - I'd say most of the good programmers I've met may be musically skilled but fail to improvise on a tune they've never heard before. Come to think of it - of course there must be exceptions - it's just that I've yet not came across one. Is it so that any really good programmer will "fail" to improvise (add value) to an unknown tune?

Steve Campbell sa...

There was a study of successful ice-skaters that compared their practice sessions with less successful skaters. What they found was that everyone practiced for the same amount of time, but the successful ones tried the harder moves more often.

To draw the parallel to great programmers, I think they just try the harder things more often - they push themselves. They fail more often, and learn from those failures. What they learn is internalized into various abstractions that allow them to work at a different level.

Anonym sa...

i think its abt abstractions.

Anonym sa...

You are applying an inside-out perspecive. Some of the best programmers I know take a personal interest in the problem domain and have the ability to understand the needs of a business on a high level. Other things that come to mind is the ability to apply the right levevel of quality (not necessarily the highest) and communication skills.

In a project I'd take the things above over someone who knows Lisp if that was the choice.

Anonym sa...

Nice article. You can also get freelance work exchange and recruitment process outsourcing from ICanFreelance.com