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