How to Learn to Program 11
Almost every week, I see the same question asked on different technology websites. That question, "How should I learn to program X?" Below I'll attempt to provide a considered answer that question. Other people will have different answers.
My Background
Before you read further, it would be helpful to know a tiny bit about my background. I started programming in school using TRS-80 BASIC in the early 1980s. While in college, I learned the normal languages that engineering students learned – Fortran, Watfor, BAT, Matlab, TK Solver!, and a little bit of C. My first job was writing in a language called HAL/S. You've probably never heard of it. JCL, Rexx, Pascal, PL1, and edit macros were used at that job too. Moving forward, I wrote professional code in C, C++, IBM Assembler. That lead to a full-time job writing cross-platform C/C++. I could code C++ on 4 platforms at the start (OS/2, DOS, Windows, MVS). By the end of that job, we were writing code that ran on SunOS, Solaris, AIX, HP-UX, Irix, Dec Ultrix, Dec OSF/1, Digital UNIX, Windows, and MacOS. That's a pretty large list.
I picked up a few more languages like, shell, ksh, csh, awk, perl, lexx, yacc, bison, Tk/TCL, a little lisp, etc… At that point, I'd transformed from a programmer into a software developer. Elegance mattered. Completely bug free code was important to ME, not just the boss. Linux was just starting to be useful, but writing commercial code wasn't really possible as the core 3rd party libraries in use where I worked were not available on Linux. Over the next few years, my C++ skills increased exponentially from beginner to advance levels. I became an application architect as the lead for a team of developers writing and supporting client-server CORBA programs. Eventually, my boss loaded me up with non-development work, moved me into an office away from the team cube-farm. Soon I didn't have any compilers or any development tools on my desktop and I spent days working through feature and bug lists prioritizing them for work.
I changed career paths from software development to become a systems and application architect, so my coding skills stagnated besides the little utilities that I needed to scratch an itch at home. Perl became more and more my tool of choice for these little programs. It is still what I use today even though I've played with php, Python, bash, Java, Javascript, powershell, and Ruby. These career choices have provided a completely different view of systems design, architecture, efficiency, scalability and what it takes to produce well-written code. Working in aerospace, data management, entertainment, publishing, telecom and consulting industries let me see very wide range of systems – what worked and what didn't work. Telecom taught me how to scale systems to unbelievable levels. Our uses routinely broke large commercial software systems. Scaling from 1 to 2 servers is pretty easy, scaling from 1 to 100 or 1,000 servers takes a different type of knowledge. It also taught system redundancy architecture. These are skills that most software developers don't learn until it is too late – after a failure. On to the programming.
Expected Timeline
Just like anything else that is highly rewarding, learning to program takes years of practice. Sure, after a few days in any language you will be able to hack something useful together, but let me assure you, that first code will look nothing like what you would write after a year or 5 or 10 as you learn more about a specific language. Everyone learns at different speeds. A few can work their way to expert level in a language after 3 years, but for most it will take 5-10 years of daily practice. As with most things, you have no way to know your own skill level since you don't know what you don't know. Usually when you think you've learned everything, then you are really just entering intermediate levels of knowledge. Please keep that in mind.
Year 1 – Apprentice in 3 Languages
In the 1st year, you will be learning concepts. To me, there are 3 general types of computer languages. Procedural, Object Oriented and Functional. For the first few months, concentrate on a procedural language like C, Python, Pascal, Perl, bash, or PowerShell. Learn the basics of functions, subroutines, passing parameters, and data structures. Data structures will be key across every language that you learn. Pointers are something that many of the newer languages hide from programmers, but those are a key concept that must be learned, IMHO.
Using pointers in C or C++ implies that you understand memory management. Learning this will help you make all your programs more efficient regardless of whether the specific language you are using supports pointers or not. Under the covers, almost every language uses pointers. In your first year, you'll also want to learn about automated testing, bug tracking, documentation, and version control systems.
Version control, even on 1-person projects, has saved me more times than I care to admit. These days, git is the defacto-standard tool. I don’t see any reason to bother with any other tool at this point. BTW, git != github. I don’t use github much at all. Running your own git repo is so very easy anyway.
Years 2-5 – Deeper Level Learning
During the 1st year, you will see all sorts of other languages and learn enough to get something done in them, but you probably won't have time to study them in depth. In years 2-5 you'll want to transition into OOD/OOP and/or functional languages. These will make you much more capable and lead to higher coding efficiency. You'll spend much less time coding, but get much more quality code written. Memory management will be 2nd nature, client/server programming will be easy for you. You'll understand why commercial programs can't run under a different operating system or under a different CPU architecture without lots and lots of work. Some of these things are taught in computer science, but I didn't take any CS classes, so I never learned this until later. You'll also learn to appreciate some commonly used development tools like version control systems, memory leak finding tools, debuggers and hopefully, you'll learn to include extensive logging in all your programs and a take your exception handling code beyond beginner levels. You'll also probably become a design patterns and best practices junkie.
For me, the Effective C++ and More Effective C++ books helped. Lots of really smart people came before us, we should learn from them to avoid making the same mistakes over again. For example, multiple inheritance is not a good idea 90% of the time. Building automatic test cases as part of your coding is brilliant – be certain you do this sooner than later. Make it a part of your development process. Knuth's books rock as do data structures revisited. Many of my perl programs these days work on arrays of arrays of hashes, just sayin’.
Years 5-10 – Expert Level in 1-3 Languages
In later years, you will be mentoring newer programmers into software developers. Teaching a concept to someone else forces you to a newer level of understanding. You may be able to add and subtract in HEX in your head. There will be so many itches that you won't be able to scratch them all. You'll have the tools, knowledge and skill to solve pretty much any problem. Unfortunately, your boss will probably give you work that prevents any coding from happening unless you specifically avoid management.
Language Recommendations
First Language – Python
Python has many things going for it. It
- is new-user friendly; working code runs easily
- let's you be productive after just a few days
- runs on all the major platforms and OSes
- isn't too slow to be useful
- has lots of 3rd party libraries to make us more efficient
- forces clean coding styles
- supports OOD/OOP techniques
- is used in some non-trivial, real-world programs
- isn't just a GUI language
- isn't just a web front-end language
- isn't just a server language
For people who want to learn to program, I've been sending them to the MIT OpenCourseware Intro to Computer Science lectures. You get world class knowledge there. If you are in a hurry, I'd guess a motivated student can work through it in a week or two. 8 weeks would be about average assuming the student covers 3 lectures and assignments each week. Be certain that you learn to use external modules or packages too. Try to find a package written by someone else before you head off and reinvent the wheel.
I'm not saying that you need to avoid all other languages, just that you should concentrate on Python to learn the basic skills of programming, data structures, version control, testing, debugging and design patterns. You will see other languages, but please try to stay with Python for a month or 6 to solidify the topics covered in that MIT Courseware. Other Python learning resources:
- Python for Beginners
- Learn Python the Hard Way – This is the best way to learn to program that I’ve found. The Hard Way.
- The Python Tutorial
Another, highly recommended, general programming resource: - How to Become a Hacker – yes, you want to be a hacker. Hacking has nothing to do with breaking into systems.
Second Language – C
C? Why not Java or C# or {insert favorite language}? Simple. This is the language that operating systems are written in. If you want to be efficient with computing resources, not waste memory, CPU, and have the fastest possible code, then C is probably the language you need to know. Embedded systems provide SDKs in C. Most scripting languages have "bindings" to call C functions. C is a language to know, for certain. Obviously, if you have a job that says you need to learn Java or Ruby or Php or Perl instead of C, then do that. Getting paid is a good thing. Other languages are mostly written in C, so if you understand how to use C, then you can guess the most likely way that the language creators actually implement the features of their language. You'll understand why garbage collection in Java and other languages makes things easier, and what the trade-offs were. C is also a compiled language. Learning a compiled language is key to your transition from programmer to software developer. C language code is converted into machine code through compile and link steps. C is also extremely cross platform, if you don't use an IDE or platform specific extensions. Chances are by this point, you've seen batch scripts, shell scripts, SQL commands. I'm not saying to completely ignore these other languages, but I am saying that concerted effort to learn C will pay off 50x more down the road.
Third thru Twentieth Languages
Whatever is needed for the problem or the language best suited to earn money is next. Picking up computer languages becomes like learning a new vocabulary word. There are hundreds if not thousands of computer languages. Each has a specific use-case. Use the right tool for the job. That's the real skill to learn here. Writing a parser in C is possible, but probably not a good idea. Using Perl or lex + yacc probably makes more sense. If you've never looked at these tools/languages, then you won't know it. C isn't the best tool always, neither is python. What's that old saying? If the only tool you know how to use is a hammer, then everything you see starts to look like a nail. You don't want every programming problem to look like C (a hammer) can solve it when that isn't the best answer. It is unlikely that every problem needs a nail, right? Every language that you add to your toolbox makes you a better, more efficient, programmer.
Specific Language Recommendations
- Python – Great beginner language
- Ruby – Makes developers highly efficient; Object Oriented.
- Perl – Lots of administrative tools are written in Perl. CPAN is awesome. OO extensions, but the programmer really has to strive to write OO code. Extremely memory and performance efficient.
- Java – Extensively used in large enterprises. Also the language for Android development. OO.
- Objective C – The language that Apple likes. Required for iPhone and iPad development.
- C++ – Object Oriented / OO.
- C# – OO, Microsoft platforms only. Hides memory management.
- Lisp – I don't know enough about this, just that lots of computer friends recommend it. emacs.
- Smalltalk – Most OO languages learned from Smalltalk.
- Javascript – Yuck. I'm not a fan. Unfortunately it is the main language running inside web browsers for AJAX calls. Most people use front-ends to javascript these days – like coffeescript.
- SQL – If you need to interface to a database, you'll need to know SQL at some level.
Sorry if I've slighted your favorite language. We all have different histories.
IDEs – Integrated Development Environments
IDEs are wonderful, after you have the basics down. Until you get there, it is best to avoid all IDEs so you don't miss out on learning some of the ugly parts of programming. It also means you'll appreciate what an IDE does for you later. Start out with a simple text editor – vi, emacs, notepad++ on Windows. This recommendation is most important for compiled languages like Java or C or C++. You need to learn the ugly parts so when something goes wrong in your IDE of choice later – and something will go wrong – you will be able to quickly recognize the issue and solve it. Some IDEs encourage the programmer to use platform specific extensions which make taking that code to other platforms extremely difficult. That's fine if you never intend for the program to run on any other platform. OTOH, porting an Objective C program written for OSX to run under MS-Windows or Linux isn't easy. Perhaps if cross-platform libraries and tools were selected at the start, then those ports would be much easier? Remember my background. I know cross-platform development. Similarly, using any DotNET extensions is a sure way to prevent your code from porting to Linux, Solaris, or OSX. Microsoft's IDEs make building MS-Windows specific programs easier than any other tool. It also is extremely difficult for a programmer to not get locked into Windows-only coding. After you've gone through the pain of not using an IDE for the first compiled language you learn, you don't need to do that again for any other language after a few weeks. However, when you start using any new language, you need to do it without an IDE to gain the understanding of how things work under the IDE.
Practice
Regardless of which language(s) you choose to learn, there is no substitute for practice. Write programs using the language even when you know you could do it in another language quicker.
Review Code from Other Experts
Looking at other people's code in the new language is extremely helpful too. I didn't say skimming – I said look. Try to understand everything in their code. Rewrite parts of it yourself. Just looking at someone else's code only gets you 20% of the knowledge. It is when you change it yourself that really makes your brain understand. Run it in a line-by-line debugger too.
So now you just need to get started. Nothing can replace practice – hours, days, weeks, years of practice.
My only question is this: what do you program during this time if it’s not part of your job? I’ve looked high and low for open source projects that aren’t so huge that they’re beyond a newbie like myself, yet aren’t so small that they disappear overnight. I can’t find any. :/
Scratch an itch that you have
After you pick a language to learn, visit freshmeat.net , find a project written in your language of choice. If you can’t find one, create one. Post it on github, blog about it.
If you start out following the MIT Courseware link above, you’ll have lots of exercises to start. Those will lead to other ideas.
I doubt that anyone who finishes those assignments won’t have 20 other ideas for small projects they could do on their own.
Do any other readers have ideas?
MY background: 20+ years professional programing. MS in Computer Science + 30 hrs graduate study in Software Engineering. Programmed in Gov’t VA loans, NASA/aerospace, Web tools, and Retail. Currently a Java guru, formerly C++, C, SQL, Lisp, Pascal, Fortran, Clips, Basic, plus Unix shell scripting. (Some Assembly and Ada too, but no guru there)
I agree with your general recommendations, but I think it’s flawed to expect a certain level of language proficiency based on the number of years experience.
Just because someone has programmed for 10 years in a language doesn’t make them an expert. The person might only be scratching the surface of what can be done within a language and never break out of the beginner/intermediate level of programming. I’ve seen this far too often. I think it takes a passion for programming to achieve an expert rating.
And depending on the level of passion someone else could become an expert sooner than 5 years, though I would think 5 is close to the minimum for a new starting out programmer. But once a person is an expert in one language, it shouldn’t take more than a year or two to become an expert in another language. But the shortened timeline is only possible because the potential to reach expert level is already there and the fundamental understanding of how computers and languages work.
As far as first languages go, I think it depends on what you need to do. I think I’m going to start my 8 year old son on Java or possibly C++. Mostly because we have a Lego Mindstorms brick that I’d like him to be able to program. Robotics seems like a good place to start, since the programs will be to get him interested and have immediate visual/physical feedback. Plus Legos are cool. Legos + Java == heaven
I’ve started a basic CS course in my High School. The first “real” programming we’ve done so far is java in the Netbeans IDE. While I don’t want to deviate too much from this for the sake of the class, how can I do this in a way that I can learn the most?
John – excellent description. I’ve read “10,000” hours as the magic number to achieve expertise in a field which matches the few years to achieve expert level (given a few hours a day which matches your time frames).
I’ve also read that sometimes the struggling point (“dip”) can be shorter or longer depending on the skill set.
Al C – I think we learn the most when working on things we enjoy that connect to the bigger picture for us. In terms of class, I’d hope every teacher would encourage interested students to do more and go beyond just the assignments. In the end, as students we should meet the class requirements, and then use them to learn more and build better, possibly more interesting solutions while not skipping the basics. :-)
Codecademy is sponsoring a year of weekly programming lessons in 2012.
I like this mucho. Once a week, learn something and back up the knowledge with an assignment.
I just hope they aren’t pushing Javascript.
Came across this site today. They have free training online and mobile apps teaching Intro, C, C++, OOP, Java, and Objective-C. The mobile apps may be paid, I didn’t look too hard.
Javascript required, yuck, but the videos are free.
wow. you’ve got some deep experience in programming languages. most of them I haven’t even heard. ^^
I always try to be skeptic towards any language and I would like to ask, why does Javascript disgusts you?
why does Javascript disgusts [sic] you
Disgust is a strong term. Dislike would be more appropriate.
The title of this article is How to Learn to Program. JavaScript is a specialty language, not a general purpose language. If you are trying to learn to program, there are many better choices than JavaScript. That is the main reason I don’t think most beginning programmers should bother with Javascript, at least not as their first language.
Why NOT Javascript
Yes, javascript has a place, but not as a learning language or as a general purpose language for developing desktop apps, server apps, or even most of web apps. IMHO, javascript should be used only when absolutely required for webapps with AJAX and drag-n-drop requirements.
Why Javascript?
Using Javascript is better than deploying a Java Applet. ;) I’m not a fan of Java for anything other than server-side programs.
Opinion
Most of this comment is opinion, not fact. That means others will have a different opinion. I could even have some of the items completely wrong.
A last question
Q: Have you ever seen a javascript program that you thought was beautiful and elegant?
i see, thank you.
I’m still a beginner in this programming field. I only know the basics of js but I had skimmed through javascript codes of other people and i sort of find it unruly. But I think it depends on the programmer to write js elegantly.
have you tried or read about node.js?
My original How to Become a Hacker link is gone. That is a new one, updated May 2012.