Programming languages rise and fall with the solar cycle.
A programmer's career should not.
While it is important to teach languages relevant to employers, it is equally important that students learn how to teach themselves new languages.
The best way to learn how to learn progamming languages is to learn multiple programming languages and programming paradigms.
The difficulty of learning the _n_th language is half the difficulty of the (n-1)th.
Yet, to truly understand programming languages, one must implement one. Ideally, every computer science major would take a compilers class. At a minimum, every computer science major should implement an interpreter.
The following languages provide a reasonable mixture of paradigms and practical applications:
- Racket;
- C;
- JavaScript;
- Squeak;
- Java;
- Standard ML;
- Prolog;
- Scala;
- Haskell;
- C++; and
- Assembly.
Racket, as a full-featured dialect of Lisp, has an aggressively simple syntax.
For a small fraction of students, this syntax is an impediment.
To be blunt, if these students have a fundamental mental barrier to accepting an alien syntactic regime even temporarily, they lack the mental dexterity to survive a career in computer science.
Racket's powerful macro system and facilities for higher-order programming thoroughly erase the line between data and code.
If taught correctly, Lisp liberates.
- How to Design Programs by Felleisen, Findler, Flatt and Krishnamurthi.
- The Racket Docs.
C is a terse and unforgiving abstraction of silicon.
C remains without rival in programming embedded systems.
Learning C imparts a deep understanding of the dominant von Neumann architecture in a way that no other language can.
Given the intimate role poor C programming plays in the prevalence of the buffer overflow security vulnerabilities, it is critical that programmers learn how to program C properly.
- ANSI C by Kernighan and Ritchie.
JavaScript is a good representative of the semantic model popular in dynamic, higher-order languages such as Python, Ruby and Perl.
As the native language of the web, its pragmatic advantages are unique.
- JavaScript: The Definitive Guide by Flanagan.
- JavaScript: The Good Parts by Crockford.
- Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript by Herman.
Squeak is a modern dialect of Smalltalk, purest of object-oriented languages.
It imparts the essence of "object-oriented."
Java will remain popular for too long to ignore it.
- Effective Java by Bloch.
Standard ML is a clean embodiment of the Hindley-Milner system.
The Hindley-Milner type system is one of the greatest (yet least-known) achievements in modern computing.
Though exponential in complexity, type inference in Hindley-Milner is always fast for programs of human interest.
The type system is rich enough to allow the expression of complex structural invariants. It is so rich, in fact, that well-typed programs are often bug-free.
- ML for the Working Programmer by Paulson.
- The Definition of Standard ML by Milner, Harper, MacQueen and Tofte.
Though niche in application, logic programming is an alternate paradigm for computational thinking.
It's worth understanding logic programming for those instances where a programmer may need to emulate it within another paradigm.
Another logic language worth learning is miniKanren. miniKanren stresses pure (cut not allowed) logic programming. This constraint has evolved an alternate style of logic programming called relational programming, and it grants properties not typically enjoyed by Prolog programs.
Scala is a well-designed fusion of functional and object-oriented programming languages. Scala is what Java should have been.
Built atop the Java Virtual Machine, it is compatible with existing Java codebases, and as such, it stands out as the most likely successor to Java.
- Programming in Scala by Odersky, Spoon and Venners.
- Programming Scala by Wampler and Payne.
Haskell is the crown jewel of the Hindley-Milner family of languages.
Fully exploiting laziness, Haskell comes closest to programming in pure mathematics of any major programming language.
- Learn You a Haskell by Lipovaca.
- Real World Haskell by O'Sullivan, Goerzen and Stewart.
C++ is a necessary evil.
But, since it must be taught, it must be taught in full.
In particular, computer science majors should leave with a grasp of even template meta-programming.
- The C++ Programming Language by Stroustrup.
- C++ Templates: The Complete Guide by Vandevoorde and Josuttis.
- Programming Pearls by Bentley.
Any assembly language will do.
Since x86 is popular, it might as well be that.
Learning compilers is the best way to learn assembly, since it gives the computer scientist an intuitive sense of how high-level code will be transformed.
Computer scientists should understand generative programming (macros); lexical (and dynamic) scope; closures; continuations; higher-order functions; dynamic dispatch; subtyping; modules and functors; and monads as semantic concepts distinct from any specific syntax.
- Structure and Interpretation of Computer Programs by Abelson, Sussman and Sussman.
- Lisp in Small Pieces by Queinnec.
This is an excerpt from a short article titled "What every computer science major should know" written by Matt Might.