Skills Needed in Programming
I'm not going to claim that programming is easy, but I am going 
to say that it is not hard for the reasons people usually assume 
it is.
Programming is not a deeply theoretical subject like Chemistry 
or Physics; you don't need an advanced degree to do well at it.
(There are important principles of Computer Science, but it's 
possible to get a degree after studying them and to have only 
vague ideas of how to apply them to practical programming.
Contrariwise, we'll experience many important Computer Science 
lessons by the seat of our pants, without bewildering ourselves 
with abstract notation; there are plenty of successful 
programmers who don't have Computer Science degrees.)
Comparing programming to some physical tasks,
programming does not require some 
innate talent or skill, like gymnastics or painting or singing.
You don't have to be strong or coordinated or graceful
or have perfect pitch.
Programming
does,
however,
require care and craftsmanship, like carpentry or 
metalworking.
If you've ever taken a shop class, you may remember that some 
students seemed to be able to turn out beautiful projects 
effortlessly, while other students were all thumbs and made the 
exact mistakes that the teacher told them not to make.
What distinguished the successful students was not that they 
were better or smarter, but just that they paid more attention 
to what was going on and were more careful and deliberate about 
what they were doing.
(Perhaps care and attention are innate skills too,
like gymnastic ability; I don't know.)
Some things you do need are
(1) attention to detail,
(2) stupidity,
(3) good memory,
and
(4) an ability to think abstractly,
and on several levels.
Let's look at these qualities in a bit more detail:
- attention to detail
In programming, the details matter.
Computers are incredibly stupid (more on this in a minute).
You can't be vague; you can't describe your program 3/4 of 
the way and then say ``Ya know what I mean?'' and have the 
compiler figure out the rest.
You have to dot your i's and cross your t's.
If the language says you have to declare variables before 
using them, you have to.
If the language says you have to use parentheses here and 
square brackets there and squiggly braces some third place, you have to.
 - stupidity
Computers are incredibly stupid.
They do exactly what you 
tell them to do: no more, no less.
If you gave a computer a 
bottle of shampoo and told it to read the directions and wash 
its hair, you'd better be sure it was a big bottle of 
shampoo, because the computer is going to
wet hair, lather, rinse, repeat,
wet hair, lather, rinse, repeat,
wet hair, lather, rinse, repeat,
wet hair, lather, rinse, repeat, ...
I saw an ad by a 
microprocessor manufacturer suggesting the ``smart'' kinds of 
appliances we'd have in the future and comparing them to 
``dumb'' appliances like toasters.
I believe they had it backwards.
A toaster (an old-fashioned one, anyway) has two 
controls, and one of them is optional: if you don't set the 
darkness control, it'll do the best it can.
You don't have 
to tell it how many slices of bread you're toasting, or what 
kind.  (``Modern'' toasters have begun to reverse this trend...)
Compare this user interface to most microwave ovens: they 
won't even let you enter the
cooking time
until you've entered the 
power level.
When you're programming, it helps to be able to ``think'' as 
stupidly as the computer does, so that you're in the right 
frame of mind for specifying everything in minute detail, and 
not assuming that the right thing will happen unless you tell 
it to.
(This is not to say that you have to specify everything;
the whole point of a high-level programming language like C
is to take some of the busiwork burden off the programmer.
A C compiler is willing to intuit a few things--for example,
if you assign an integer variable to a floating-point variable,
it will supply a conversion automatically.
But you have to know the rules for what the compiler will assume
and what things you must specify explicitly.)
 - good memory
There are a lot of things to remember while programming:
the syntax of the language,
the set of
prewritten functions
that are 
available for you to call and what parameters they take, what 
variables and functions you've defined in your program and how 
you're using them, techniques you've used or seen in the past 
which you can apply to new problems, bugs you've had in the 
past which you can either try to avoid or at least recognize by 
their symptoms.
The more of these details you can keep in your head at one time
(as opposed to looking them up all the time),
the more successful you'll be at programming.
 - ability to abstract, think on several levels
This is probably the most important skill in
programming.
Computers are some of the most
complex systems we've ever built, and if while
programming you had to keep in mind every aspect
of the functioning of the computer at all levels,
it would be a Herculean task to write even a simple
program.
One of the most powerful techniques for managing the 
complexity of a software system (or any complex system)
is to compartmentalize it into little ``black box''
processes which perform useful tasks but which hide
some details so you don't have to think about them
all the time.
We compartmentalize tasks all the time, without even
thinking about it.
If I tell you to go to the store and pick
up some milk, I don't tell you to walk to the door,
open the door, go outside, open the car door, get in
the car, drive to the store, get out of the car, walk
into the store, etc.
I especially don't tell you, and you 
don't even think about, lifting each leg as you walk, 
grasping door handles as you open them, etc.  You never 
(unless perhaps if you're gravely ill) have to worry about
breathing and pumping your blood to enable you to perform all 
of these tasks and subtasks.
We can carry this little example in the other direction, as well.
If I ask you to make some ice cream, you might
realize that we're out of milk and go and get some 
without my asking you to.
If I ask you to help put on a party for 
our friends, you might decide to make ice cream as part of 
that larger task.
And so on.
Compartmentalization, or abstraction,
is a vital skill in programming,
or in managing any complex
system.
Despite what I said in point 3 above,
we can only keep a small number of things in our head at one time.
A large program might have 100,000 or 1,000,000 or 10,000,000 lines of code.
If it were necessary to understand all of the lines together 
and at once to understand the program,
the program would be impossible to write or understand.
Only if it is possible to think about small pieces
in isolation
will it ever be possible to work with a large program.
Compartmentalization,
powerful though it is, 
is not
automatic,
and not necessarily an instant cure for all of our 
organizational problems.
We carry a lot of assumptions 
around about how various things work, and things work
well
only as long as these assumptions hold.
To return to the previous example,
if
I ask you to go 
the store and get some milk, I'm assuming that you know which 
kind to get, where the store is, how to get there, how to
drive if you need to, etc.
If some of these assumptions 
weren't valid, or if there were several options for any of 
them, we might have to modify the way I gave you
instructions.
I might have to tell you to drive to the store,
or to go to Safeway,
or to get some two percent milk.
Therefore, we can't simply compartmentalize all of our 
processes and subprocesses and forget about complexity problems 
forever.
We have to remember at least some of the assumptions surrounding the 
compartmentalization scheme.
We have to remember what we can and can't expect
from the processes (people, computer programs, etc.) which
we call on to do tasks for us.
We have to make sure
that we keep our end of the bargain and don't fall down on 
any of the commitments and promises we've made on the tasks we've been asked 
to do and which others are assuming we'll keep.
Thinking about the mechanics of a design hierarchy,
while also using that hierarchy to avoid having to think 
about every detail of it at every level all of the time,
is one of the things I mean by ``thinking on several levels.''
It's tricky to do
(obviously, it's tricky even to describe), but it's the only 
way to cut through large, complex problems.
 
What's hard about programming (besides maybe having trouble 
with the four traits above) is mostly picky little detail and 
organizational problems, and people problems.
A large program 
is a terribly complex system; a large programming project 
worked on by many people has to work very hard at peripheral, 
picayune tasks like documentation and communication
if the project is
to avoid 
drowning in a flood of little details and bugs.
Read sequentially:
prev
next
up
top
This page by Steve Summit
// Copyright 1995, 1996
// mail feedback