This work is licensed under the Creative Commons Attribution 2.5 License (or at your option a greater version of it).

One note that is in order is that you shouldn’t feel bad about having followed a different ordered in the programming languages you’ve learned. By all means, you can still learn things on your own otherwise.

As for how I started programming myself, I should note that I learned BASIC at the age of 10 (back in 1987), and then learned C when I was 15 years old (in 1992); I later learned Visual Basic for Applications and when I was 19 years old I was introduced to Perl and UNIX at my workplace, which was a web site creation shop (back in 1996, when the Internet started to become popular). I have later learned other languages and technologies and still do to a large extent.

First, I will mention several approaches taken by other people who discussed this issue before, and try to explain why I disagree with them. Then I will propose and explain some relations (“Language A should be learned before Language B”) that are good to follow. After that, I will propose my verdict, and discuss some orthogonal alternatives. Finally, I will discuss some different types of teaching and how each should be conducted differently.

The purpose of this essay is to contemplate what is the best introductory programming language to teach for beginning programmers, or for a beginning programmer to learn on his own.

There is a myth that programming using a text editor and a command line is too difficult for mortals. This is false because, as late as the 1980’s or 1990’s, almost all personal computers used a command-line interface (often a BASIC interpreter or DOS), and required programming using non-graphical editors, and it was still adequate for most people. (To say nothing of earlier interfaces such as Teleprinters (TTYs) or punched cards). Plus, it is hard for a programmer to avoid typing code entirely.

Programming does not happen in the IDE - it happens in the mind. Programmers should learn to write code that does something. By using the text editor (of the IDE or a standalone one) and writing text that does something, they can best learn to program for the real world.

Many education institutions reject many languages as introductory languages because they don’t have a decent integrated development environment (or IDE for short). An IDE as useful and convenient as it is, however, is not an absolute requirement.

I don’t expect them to become superb programming in a day. Becoming a better programmer is a process, and cannot be taught in a semester or a year of hard work.

Often, the trial and error will be good for them. Plus, even writing some disorganised, but functional code is better than the program taking them much more time to write (and more time to read and understand after writing).

It may actually make them think programming is loathsome or otherwise a very strict process instead of a very creative process.

The more strict the language is, then generally the less expressive it is. Programmers like to express themselves and be able to implement algorithms using the entire power of the language. They don’t want to declare a lot of type definitions, many constraints, write a lot of syntax, or otherwise be encumbered in the way.

You many times hear people saying that beginning programmers should be taught using a programming language that restricts them and forces them to write good code. Languages like Pascal, Ada, Java, and many others were designed to try to save programmers from themselves. And indeed many people believe that programmers should start learning from such a language.

While the efficiency of algorithms and the underlying implementation of language primitives should be stressed at a certain point, the first task of an introductory course is to make sure a programmer can learn to write code, not necessarily the most efficient one. (Not even according to asymptotic complexity). Learning how to write quick and dirty code is a mental leap that is large enough as it is.

Spolsky’s argument about the efficiency of some operations is wrong, because programmers who learn such languages won’t often notice the difference from such inefficient operations, due to the incredible speed of contemporary computers and the fact that their data sets are generally too small. Moreover, many instructors and exercise checkers won’t penalise for the presence of such issues in their homework.

A good introductory programming language should allow you to write a lot of useful code quickly, and not slow you down with many low-level constraints. Beginning programmers have a hard enough time learning how to translate their thoughts and intentions into working code, and solving bugs and the last thing they need is to deal with too many idiosyncrasies of the language only because it is too low-level.

All this work to do something that in high level, garbage collected, languages is as simple as $result = $object1 OP $object2; . From my experience with Technion students, they are often get so bogged up in the technicalities of working with C instead of getting quick, dirty and useful code running.

However, C has one major deficiency: it’s too close to the processor to be useful. In order to perform an operation on two objects, one should allocate them first, perform the operation, and then take care of freeing both objects and the result (to say nothing of edge cases where allocating or freeing may fail.).

C and C++ have been popular introductory languages for teaching programming for many years now. While some schools have switched to teaching Java or a different language, C and C++ are still very popular.

In his “Back to Basics” essay , Joel Spolsky gave a case for teaching C as an introductory language instead of more high level languages. His argument is that programmers will end up writing sub-optimal code because some low-level elements of dealing with strings and arrays are abstracted away in higher-level language.

I believe an introductory language has to grow with you. When I studied BASIC, I was able to use it for programming games, graphical demonstrations and animations, scripts, and other uses. I continued to use BASIC on DOS and Windows, until I learned the much-superior Perl, which I’m using today.

Most of the SICP exercises are about number theory, recursion, and a lot of other relatively abstract stuff, and too few are about real world and exciting tasks: writing games and other demos, working with files, writing scripts and utilities, networking and working with the WWW, etc. In fact, the Scheme standards define too few useful things. Most of the dazzling number of different Scheme implementations all extend the language in several ways, but all have their own idea of how to do it. Compare it to Perl, Python and friends which have one main C-based implementation, or to C where the standard library is actually quite useful.

However, there are several problems with teaching Scheme as an introductory language. The first is that it is too impractical. Scheme does not have system primitives that more modern languages take for granted like ones for random file and directory I/O, sockets, graphics primitives, Graphical User Interface (GUI), etc. Moreover, the core language is limited and most practical code tends to become very verbose in it. For example, whereas in Perl one would write $myarray[$i]++ to increment an array element by one, in Scheme it would be: (vector-set! myarray i (1+ (vector-ref myarray i))) .

I have read the book in my third semester of the Technion (without doing the exercises) and later took both of the SICP courses that were given by my department. I learned a lot from the book, and while the courses did not teach me too much new, I did enjoy working on the exercises.

“Structure and Interpretation of Computer Programs” (or SICP for short) is a classic text and course material on programming, taught at MIT and many other universities around the world. SICP uses Scheme (a minimalistic dialect of Lisp) as its exclusive language to cover many important programming and meta-programming concepts.

McIver’s approach is flawed in the sense that she is trying too hard to save the students from all possible problems they may encounter in trying to understand their introductory language. However, programming is hard to learn, and learning the first language is always difficult. Creating a “flawless” language that lacks any sex-appeal is not going to make it better, but much worse as both the professors and programmers will detest it.

This is a language that I won’t enjoy programming in. And I don’t believe a professor who doesn’t enjoy programming in a certain language can effectively convey it to his students, while lacking the enthusiasm and love for the tool he chose.

When I program, I’m using every tool in my arsenal, and expect the language to be powerful enough to be able to translate my thoughts into code. McIver’s language is too limited and limiting, to be effective for programming in, and being planned exclusively for beginners, lacks the richness and interesting idioms that make programmers like or even love their languages.

Now, if I had to summarise this language in one word it would be this: sexless. It’s incredibly limited, not flexible, and not fun. It has no pointers or references and instead relies on nested structures and arrays. There are two basic data types - a number and a string. The language does not have functions as first-order objects, closures, or objects and classes in the Object Oriented Programming sense. Furthermore, it has very few ways for one to express oneself. As a result implementing many algorithms would be very difficult in it.

Linda McIver published along with Damian Conway a paper titled “Seven Deadly Sins of Introductory Programming Language Design” that explains the problems they found with most popular introductory programming languages. The article makes a very good read.

Some useful relations

This section will introduce some useful relations ( “Language A should be taught before Language B”) to consider in teaching programming, and explain them. By using these relations one can more easily reach a final verdict.

A High Level Language Should Come Before C C should not be taught as a first programming language from the reasons I have mentioned above. By all means, one should use a more high level languages which supports Managed programming, and other nice high level constructs. Languages like Perl, Python, Ruby and to a lesser extent Java and .NET are much better than C as introductory languages.

Perl/Python/etc. should Come before PHP Some people believe that PHP is a suitable introductory language. However, PHP has several major problems: lack of good abstraction mechanisms, many inconsistencies, many functions to do the same thing, and many nuances to its use. People who learn PHP right away, tend to write very bad (and sometimes very dangerous) code in it, and are not well-aware of its pitfalls. PHP is a fine language for the web and for other uses, especially because its implementation makes deployment of some large-scale web applications easier. However, the other languages in the so-called “dynamic”, “agile”, or “scripting” class of languages are not harder to learn, and less problematic. So they should be taught first instead.

Perl/Python/etc. should Come before Shell Some people believe that the first language a UNIX user should learn is a good shell (such as GNU Bash or zsh). However, Shell has some issues. The first is that the mentality of the UNIX Shell is different from the mentality of conventional programming languages, and causes native shell programmers to be less capable of adapting to a different language, as well as writing sub-optimal code in shell. The second is that in traditional shell, some operations are not as efficient as they should be. While more modern variants have introduced arrays and string-wise dictionaries, they are still an afterthought. For these reasons, shell is not recommended to learn before a dynamic language.

C should Precede Assembly It is certainly a good idea to learn Assembly language, preferably of several different processor architectures. However, C should be learnt first. The reason for that is that people who dive right into Assembly, tend to write sub-optimal code because they don’t understand well how this code is executed by the processor and how to compile it. This is while programmers who’ve learned C are better equipped to understand how Assembly code works, because it is somewhat more convenient yet still very close to Assembly. A friend of mine reported that in his workplace, where they write Assembly code for various Digital Signal Processors (DSPs) some of the native Assembly programmers order their instructions in ways that are executed inefficiently because of the special processor pipeline. He then told me that C programmers who learn Assembly make better Assembly programmers.

The First Language should be Practical A good first programming language should be practical and should grow up with you. I can tell from my experiences with the various BASICs, which were the first languages I learnt, that BASIC was fun because it was useful. Using BASIC on the old Intel-based computers, one could write games, graphical demos, text processing and command execution scripts, and even serious applications. While BASIC is in today’s standards a very limited language that should no longer be taught as a first language, I still fondly remember it as being a lot of fun. I even continued using BASIC after I learned C and what was then C++, because it was quicker and more convenient. (I no longer do, because I now feel that Perl is superior to BASIC in every way, and that’s what I’m using now.) On the other hand, Scheme as in SICP is an awful choice for an introductory programming language, because it feels very impractical. Writing quick and dirty code to do a lot of things in Scheme is very verbose, and plus, the core standard lacks many primitives for common POSIX operations (like random file I/O, directories, sockets, etc.) much less useful APIs. While some Scheme implementations provide extensions to the language, they do so in different incompatible ways. Different people I talked to, agreed with me that “You cannot do anything with Scheme”. Compare it to languages such as C and C++, Perl/Python/Tcl/Ruby/PHP, Java/.NET, etc. that feel very practical, and you’ll see why hardly any industrial-strength code is written in Scheme. Teaching a language just for teaching programming with, is sub-optimal because the students cannot take this language with them and perform real-world tasks with it. They will have less motivation to experiment on their own, and to remember it for long.

Localised Programming Languages should be Avoided The Wikipedia has an (incomplete) list of non-English based programming languages, that were created at some time. What these languages try to do is make sure young children or other people who did not master the English Alphabet and vocabulary well can start learning programming without knowing English first. I see several problems with this approach. One is that it is important that children will be taught English starting from an early age - as early as possible. This is because English, being the international language, is becoming more and more important for every one to learn. Tender children who are talked to in several languages, will quickly master them, without confusing them. This will save them a lot of frustration later. (By all means if one happens to know other languages, he should talk to his children using them too, but that is beside the main point.) Knowledge of English is more important than knowing how to program. So it is a good idea that when teaching programming to teach English first as a necessary pre-requisite. The other problem I see is that such localised programming languages feel unnatural and wrong. English has the richest technical vocabulary of any other language, and some terms in English are impossible to translate to other languages. And yet another is that such languages tend to be very ad-hoc and incomplete. Finally, code that is written in them cannot be understood by programmers who don’t know this language. So, to sum up, instead of starting with a localised programming language, teach your students some basic English first. It might take longer, but will save more time and frustration later on. Plus, programming is a great way to expand one’s mastery of English, especially today when the Internet is so prevalent.