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.
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.
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.
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.
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.
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 ANSI 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.
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.[globalisation]
Joel Spolsky wrote an essay titled “The Perils of JavaSchools” where he argued that teaching Java in Computer Science curricula is inferior to teaching ANSI C and Scheme, which was what he learned. The article is wrong on many points, but it highlights some of the problems with Java.
Java is too verbose. Some people may argue that this can be solved by using a proper IDE, but as Paul Graham explains, verbose code also has the “the cost of reading it, and the cost of the space it takes up on your screen.”.
Moreover, Java code tend to be very monotonous. Almost all Java code looks the same, and feels boring.
Steve Yegge’s very funny article “Execution in the Kingdom of Nouns” illustrates another problem with Java. Everything has to be a noun, with no verbs or even the many keywords which Perl 5 is infamous for but which Perl programmers love. And instead of having some Perl 5-like operators for converting between data structures, you have a hideously long casting lines.
Java was supposed to be kept simple, and many important concepts like closures, multiple-inheritance, defining methods at runtime (a la Smalltalk), runtime code evaluation (the Lisp-derived “eval” operator, which is now common in most dynamic languages), operator overloading, and many other elements had been kept out of it. As such it turned out to be very unusable. Java 1.5/5.0 introduced many drastic enhancements, but not enough proper abstractions. As a result, Java is now bloated, but talented programmers still normally find writing code in Perl, Python and friends more natural.
Paul Graham’s essay Java’s Cover, which he wrote to explain why he decided not to learn Java is very instructive. I read Graham’s article, some time after it has been written and felt it reflected my feelings about the language. Back when Java started to become hyped , I had ended up learning Java to see what the hype was about and to write some browser applets. While having felt that I have truly understood what the essence of references in Perl 5 was, only after learning Java, I still felt that Java was too over-rated.
Perhaps I’m getting too carried away in criticising Java. My point is that, as Joel Spolsky indicated in his “JavaSchools” essay, teaching Java as the first language, makes many of the people who have learned it airheads, who cannot think outside the limited constraints that it imposes on the programmer. Teaching an expressive and rich dynamic language such as Perl or Ruby instead, will not exhibit this problem, regardless of what Joel says, as these languages constantly require a programmer to think outside the box, and introduce the programmer to many different (often built-in) patterns and paradigms.
[globalisation] A few people who read this article claimed I was advocating globalisation. However, consider what Eric Raymond writes in “How to Become a Hacker”:
4. If you don’t have functional English, learn it.
As an American and native English-speaker myself, I have previously been reluctant to suggest this, lest it be taken as a sort of cultural imperialism. But several native speakers of other languages have urged me to point out that English is the working language of the hacker culture and the Internet, and that you will need to know it to function in the hacker community.
One should note that the proliferation of English today is not the first time that there happened to be a Lingua franca in the world or a limited part of it. I also feel that having one spoken language that everyone of importance is familiar with (although possibly not so well) is better than not having any good common way of communication, and thus was shown to be inevitable times and again in history.