I happened upon a questionnaire–How did you learn to program?–and chose to take a few minutes to fill it out. Doing so forced me to look back at the years I’ve spent coding, how I got started and the lessons I’ve learned along the way.
I ended up spending a good while filling in my responses and, since there may be a worthy nugget of wisdom burried in there somewhere, am posting the main points here.
If you’re already a programmer and want to share your own story, take a few minutes to fill out Amber Case‘s survey.
In my early teens my father gave me the first computer I could call my own. It was a RadioShack TRS-80 Color Computer 3 (CoCo3) and came with a whole 128k of RAM and a cassette recorder to save programs on. Powering up would boot into a BASIC shell, displaying a blue screen and a blinking cursor that just begged to be told what to do.
My first bit of functional code ever was something like:
10 print "Hello World\n"; 20 goto 10
The few people I knew that had computers had Commodore64, Vic-20’s or such and used them solely for playing games and I have to admit, I was a little envious: I wanted cool games, too! That was the kick I needed to get started on my own programs.
I was living with my father–one of the smartest people I’ve ever known but in an absolutely non-technical way–and his reaction to my interest in computers was the same as it was for almost everything I did: a mix of perplexity and pride. Neither he, nor anyone I knew could help so I just started going through the Extended Basic manual and soon found Rainbow, an sweet mag for CoCo enthusiasts.
The first real program I wrote that was all my own was called “Sunday Driver”–a top-view driving game, with graphics, a few sound effects and joystick control and everything! It didn’t maintain a map of obstacles on the road, just randomly dropped stuff in your path and would then check for collisions by probing the color on the screen in front of the car. If you didn’t hit the exploded tire, or whatever, “just right” the collision dectection would fail and you’d drive right through it (I can think of 3 trivial fixes now but, at the time, estaba un problema!).
Eventually, I would discover that working out the solution–the “how” a game would be programmed–was may more enjoyable than actually playing the games.
After highschool, hormones and life drew me away from the keyboard. A few years later, while I was back in school studying physics at university, two things happened:
- I did some research using an AFM
- I discovered Linux
I had a study to do on friction (as part of the first group of students to get to play with an Atomic Force Microscope), and wanted to compare the results we were seeing with a theoretical model. My girlfriend had a spiffy new desktop computer, and along with it came my old friend: the BASIC interpreter.
With a bit of a refresher from the help files, I managed to write a discreet event simulation of two interacting forces (a charged particle and a simple molecular spring). After taking the computer hostage for three days, as it slowly ran the simulation, I managed to derive both basic conservation of energy laws and a nice model of friction at the atomic scale (the particle was slowed after passing the spring, while the spring was jiggling with thermal energy). That adventure re-awakened the thrill of creating something powerful with nothing but time and intelligence.
Around the same time, we had to use the strange “Linux” computers in the lab… that was the true beginning of my programming adventure. I wound up spending 6 months cocooned with a new computer, learning the ins and outs of Linux and the C programming language along the way.
I learnt it all using manpages, help files, a few online resources (thank you, gopher) and the host of professional-grade tools that came with Linux.
Learning to code
Pretty much everything I learned was through a combination of absorbing documentation and lots of trial and error.
Procedural programming was a natural extension of my tendency to chunk a problem down into smaller and smaller steps, so getting it was mostly a matter of learning syntax and that happened very quickly.
Discounting my ~5 year hiatus, it was a couple of years after starting up with coding under Linux when I really got it. The key, for me, was OO.
Object orientation shifted the problem from that of creating a flowchart to something more interesting, that provided a truer reflection of the problem at hand and the world in which it transpires. I sometimes think that my job is mostly about “naming things”, just making a drawing of all the various names (objects) and the actions they can perform (methods).
“A car has an engine and wheels, an engine has a transmission, a transmission sends power to wheels… etc.” We already have three types of object, linked together by composition, and a method. Getting it coded after that may not be trivial, but is straightforward.
So grokking it really came down to:
- discovering OO
- learning from others–the Gang of Four’s “Design Patterns” was invaluable
- getting a few languages under my belt (C++ and Perl, first, then many others)
and spending a couple of years solving real-world problems.
Starting a career
When I applied for my first IT job, they told me they were a Perl shop and that I’d have to pass a test to get in. “No problem,” I said, ” I’m good with Perl.”.
Hum… I actually had never even heard of the language, but I got an O’Reilly and spent the weekend learning… mostly about regexes. Best investment ever.
I passed the test, got the job, and went from there, to California, and then to consulting for the last decade or so.
I’ve done a great many projects, both professionally and personally, and each one has a special place because it’s like that song you listened to repeatedly in the summer of XYZ.
Hearing, or just thinking of, it brings you back to that time, reviving a flash of the feeling of being there, as the person you were, and the lessons you learned.
So I have both attachment to and pride in each one, and it’s hard to decide which would be my all-time favorite. However, there is this one project…
Back when I was getting a little bored with my first IT job, I started looking for a little sugar on the side. I was pitching for a consulting job, for which I was offering two solutions: either Windows or Linux based. The Linux solution was perfect, except that it didn’t have a voicemail/auto-attendant system. So I started writing one.
When I didn’t get the contract, I was halfway done and decided to press forward. I created a complete call answering and vm system and, when it was ready, released it as my first real free software/open source project.
My father said: “What? You’re just giving it away?!” He didn’t get it, I was contributing back to the community that had given me so much. Karma being what it is, a few weeks later, after arriving late for work because of a snow storm and in a melancholy mood, I had an email waiting for me. “Hi! Loved your project. Feel like joining my startup in California?” Within two months, I was moving south.
That software was useful to many, and it brought me many places. It generated articles in a few mags (like SysAdmin) and helped me realize what you could do with a little creativity and the willingness to give it away. Though its unmaintained and has been surpassed by projects like Asterisk, I’ve left an archive of the site up all this time.
$0.02: Advice for beginners
This is the advice I’d give to anyone who wants to be a professional programmer.
The short version is: learn to code, then focus on a bigger picture. You will develop into a well-rounded, skillful and valuable asset for any project you contribute to.
Start by learning the basics of a language, the “hello world” stuff, and then quickly move to scratching an itch you’ve had. Think of something, not overly grandiose, you wish you had but can’t find, and try to build it. The going will be slow at first, but use google and the manual and don’t give up–you can do it.
When you get your project mostly-working, release it on sourceforge.net or the like, and ask for comments, bug reports and help. If you can find someone skillful to review your code, even better. Don’t take the critiques personally, each one can help you become better.
While you’re on sourceforge, check for projects you find cool that are looking for help. If you pitch in, you’ll get recognition and mentoring as well as a chance to see a project being built.
Once you have a handle on the language, start looking at the bigger picture. Get a copy of Design Patterns, by Gamma et. al. or other books that are less about syntax and more about the interaction between parts and the structure of what you build.
When you’re really getting comfortable with the language, learn a new one (or more). Different languages are appropriate for different tasks and, just like being a black belt in one martial art, the learning process gets easier and easier as your mind becomes nimble and you start tying new information as simple deltas to your existing mental map.
Reuse as much as possible. Use existing software, libraries and tools. Never code anything that already exists except as a learning exercise. Life is short and the world has plenty of needs to fill without wasting time doing something over. Corollary: boredom is a sign that something is wrong. If you’re cutting&pasting a lot, or find that what you are doing is dull, take a step back and rethink how your doing things. Are you sure you need to do this (maybe the problem is already solved by someone), is there a more general/reusable way that will save you some typing? You should be at 100% of your capacity, or close to it, while your at the keyboard.
Be accommodating to differences. Not everybody runs the same kind of computer, the same kind of OS. If you have a choice between a tool that supports only one environment and a tool that supports many, always choose the cross-platform option (e.g. I currently like wxWidgets for GUI programming). Same goes for written languages: even if you don’t provide translations, do your coding as if you were and it will be easy for you (or someone else) to add in localization later.
Be generous with your creativity: share code, contribute to existing projects, help others. Each of these will teach you something of value, and come back to you 20-fold. My resume used to be nothing more than a search for my name on usenet (discussion/help groups for programming and electronics).
Develop an aesthetic. Good code is lean and elegant. You’ll reach a stage where it may be tempting to flash how smart you are, with convoluted and subtle code. This is a mistake–it’s hard to debug and unmaintainable. Keep it as simple as the complexity of the problem demands. If you can let me understand what your code does at a glance, and I’ll be impressed.
Stick to open platforms and standards. Don’t get entangled with some company’s flashy development environment or hostage users. The users will eventually break free, you’ll still be trapped. If you use open software and platforms, you’ll have more users and developers and it’ll cost less. If you use open standards (like W3C HTML, or any communication protocol, format whatever), you get the benefits of the work of really smart people and open your work up to a host of unexpected future use cases.
Make the world a better place. All your programs don’t need to be about saving the whales. Anything that is useful–helping a shop ship its ceramic tiles more efficiently, whatever–liberates us, helps humans get out of drudgery and frees them to do other things. Stay away from the useless and negative, coding a spambot will hurt your pride and make us all suffer. Be proud of everything you make.
Take every opportunity to learn. Charge less, if you must, to get a chance to learn something new while you work. You’ll eventually get to a stage where you can choose to only take on projects that will make you more than before. For me, its currently about graph databases and distributed machine learning. The precise “what” will change, but the process of constant evolution makes you a better coder and a happier person.