Friday, February 8, 2013

What Separates a Great Programmer and a True Master.

The difference between an average programmer and a great programmer is very large indeed, certainly much larger than say, the difference between an average construction worker and a great one.  This observation has been discussed in numerous places, and I especially like Jeff Atwood's post on the subject over at coding horror.  In fact, I would argue that the difference between a great programmer and a true master is just as large, if not more so.

1. A master programmer is capable of learning a new language extremely quickly; not because they are so much smarter than everyone else, but because they understand how computers work on a deep level, and they understand that programming languages are merely an interface.

Learning a new programming language is certainly much less challenging than learning a new spoken language.  Why is that?  Whereas spoken languages were developed independently by many different groups of people over the entire course of human history, programming languages have been around for less than 100 years and share common historical roots.  Whereas spoken language is by it's nature ambiguous, programming languages are extremely precise.  Whereas learning a spoken language requires a great deal of memorization, learning a programming language requires a great deal of understanding.

There is just way more stuff to memorize when trying to learn a spoken language, even for a simple conversation; and although in programming you must memorize certain things, a programming language is a "machinery", and once one understands how the "machinery" works, memorization is not as useful as knowing how to figure things out from first principles.  The great masters understand that the machinery of programming languages is dictated by the fact that a programming language is merely an interface which communicates with the computer.

2. A master programmer strives to maintain maximum generality whenever possible, and is able to dramatically increase their productivity by manipulating data the "best" way, and choosing the "best" tool for every task,

A great programmer is a hacker by nature, but a true master avoid "hacks" whenever possible because they understand that it's far too easy to get backed into a corner if you do not plan properly, and then productivity suffers because it is necessary to start over from the beginning.   Programming can be extremely rewarding, as well as extremely frustrating; it can be tempting to implement a quick fix, or a "hack", when you get into a difficult situation, and sometimes it's necessary to do just that.

A true master is able to be so much more productive because they organize their code, and their time, in such a way that they maintain flexibility and they can always keep plugging away because by maintaining generality they maximize code reuseability.  Although it might take a bit more time to write code at the highest level of generality one time, the fact that this same code can be reused will pay for itself over and over again in terms of increased productivity in the future.

3. A master programmer is able to very quickly plan out solutions for highly complex problems because they are as much mathematicians as programmers.

Although it's true that a great programmer can pretty much manipulate data however they want, the great masters are able to manipulate data the "right way", in the sense of maintaining maximum generality, and they are able to rapidly find solutions where others cannot because they are able to abstract the mathematics of the situation, from what the data is supposed to represent.  In this excellent answer from math.SE on the question of why mathematicians use single letter variables, Dan Peterson writes:
I think one reason (that mathematicians use single letter variables) is that often one does not want to remember what the variable names really represent.  As an example, when we choose to talk about the matrix A_ij, instead of the matrix TransitionProbability_ij, this expresses the important fact that once we have formulated our problem in terms of matrices, it is perfectly safe to forget where the problem came from originally -- in fact, remembering what the matrix "really" describes might only be unnecessary psychological baggage that prevents us from applying all linear-algebraic tools at our disposal.
A great programmer is able to apply things they learn in one language to other languages, and for this reason learning a new language is a great way to increase one's skill level.  Similarly, a great master is able to apply things they have learned from studying the language of pure mathematics to various programming problems, and this can have an even more profound effect.

On the one hand, being skilled in coming up with and writing rigorous proofs is a great way to train oneself to being able to come up with a plan of attack for a difficult programming problem.  On the other hand, being able to formulate a programming problem as a pure mathematics problem is only as useful as the level of mathematics you have mastered.  Indeed you will never be able to make progress if you get to a point where you start trying to reinvent something like algebraic topology.  It's important to study higher mathematics precisely so that once you have abstracted away the math from the code, that you know where to look to find out how to solve it, or better yet that you remember the solution.  This is the secret by which a great master is able to so rapidly solve problems which a great programmer is either incapable of solving, or else can only solve partially after an extreme force of will.

No comments:

Post a Comment