What languages (or classes (as in paradigms) of programming languages, plus a recommended language of that class) should every computer science student be taught in college according to you? Motivate your answers; why that language? What use will one have from it? What concepts does it teach (better than language X does)?

Note/clarification: This question is about computer science with heavy focus on software engineering, not pure computer science. It is still computer science education and not software engineering education which is the focus.

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

Moreover, the vast majority of CS students are hoping to get a non-academic job after graduation. Pseudo-code isn't going to be worth much in a competitive job market. I don't think that a CS degree should primarily be job-training, but it has to make some accommodation in that direction.
–
Adam CrosslandFeb 24 '11 at 15:18

2

ALL OF THEM. If time is limited, start into the letters of the alphabet. A+, B, C, C#, D, E, F#, J, K, Q, R, T... That's not a bad list, actually.
–
Jesse MillikanFeb 24 '11 at 15:46

6

Congratulations on discovering yet another version of the "Which Language?" question. I can't wait to read all of the opinions. Don't forget the reference to SICP. Oh wait, there it is.
–
Corbin MarchFeb 24 '11 at 16:27

20 Answers
20

Assembly (a relatively simple dialect): It's important to understand at least a little of the fundamentals

C: Procedural language, used in many places. Does not burden new students with whole new concepts like OOD all at once.

Java / C# / Eiffel / C++: Something Object-Oriented is good, any one of these would accomplish the goal of teaching the students OOD and once they understand one of these languages, they should be able to learn the others.. There are many good languages, I listed Eiffel because it also has design-by-contract.

LISP and Prolog: Teaches students a whole new way to think, which is imporant, even if they never use either of these "in the real world".

SQL and XML: Introduces new ways to think about data and how to retrieve it and manage it.

Students should be exposed to all of these paradigms at the very least. Not just one or two.

I suppose many people will suggest Python to cover the procedural style, OOP style, and maybe others, but I don't have enough personal experience with Python to be able to confidently recommend it.

I would separate managed from unmanaged OO too, C++ and Java. While I have never used C++ since uni without learning about malloc, the heap and the stack, you will never be as good understanding OO.
–
markmnlFeb 28 '11 at 1:00

I personally find it somewhat sad that functional languages aren't taught as predominantly as they used to be. I think that at the very least comp sci students should be exposed to a language from all of the major paradigms: procedural, object-oriented, functional, and dynamic.

As an IT student I definitely agree. I have the benefit of working full time in the real world while I go to school as a junior level web app developer, but I feel like even if I went with a full fledged CS degree I would be missing a lot of coverage of the different paradigms.
–
Kenneth PoseyFeb 24 '11 at 15:25

Add declarative to the list (Prolog). Also some languages are explicitly parallel (Occam). Teaching students how parallelism works would be good (nobody get it correct).
–
Loki AstariFeb 24 '11 at 16:33

I think a well balanced CS student should be taught a language in each of the 4 programming language types:

Functional - Lisp/Haskell/PostScript. I don't have much experience with Haskell, but I've heard other programmers who do rave about it. Understanding the constructs of functional programming and why they're useful in many situations will help a programmer become better at organizing algorithms in other languages as well.

Object-Oriented - Take your pick. C#/Java/Python/Ruby/yadda yadda yadda. This type needs to be taught simply because that's what modern business wants.

Imperative - C/Fortran/Pascal. These are less common these days, but they should still be learned from a practical/historical perspective. The methods they employ still have practicality because in every language, it all boils down to an instruction. And imperative languages are very good at listing and following instructions.

Logical - ProLog. I have never found a good practical use for any of these languages, but I have found some of the concepts behind the logical languages handy when trying to figure out how to write some of my methods in more object oriented languages. I didn't get to focus long on the logical languages during my college years, and I think a stronger focus there might have done me some good then.

The #1 language that every graduating CS major should know is the one that maximizes their potential for landing a great job. That's going to change over time, it's going to change based on the individual's definition of great job, and it's going to vary by geographic region.

For the moment, I'll say that English is the #1 language every CS major should know (this, of course, varies by region.)

I think it changes with time, but ideally - 3 languages from 3 very different perspectives. In my day it was procedural, OO, and functional - Pascal, C++, and LISP. I'm not so so sold on particularly those three. But when I interview I look for:

Some level of experience with a
language where you have to pay
attention to memory management (C/C++
and many others)

Some level of experience with an object oriented language with expectations on API use and the various abstractions available (C++/Java)

A "stretch" language - something that is weird, hard, and challenging. I'm not going to hire because someone knows LISP, assembly, or some other challenging language, but I want to see that the engineer faced some sort of challenge that involved serious problem solving and plenty of "what the heck is this?" moments.

As another trade - I think CS programs do need to train students on prominent languages in the market place. At any given time, I think 2-3 languages have serious prominence for the majority of jobs. I think a school owes it to students to provide the opportunity to learn 2 out of 3 of those language with a depth of training available in at least one.

in order to get an idea of what is going on behind the scenes, whatever programming language you are using. it helps grasp basic concepts like dead code, and various types of optimizations that a (good) compiler will be able to do for you.

Lisp (with CLOS for OOP) and Haskell. This question is not restricted to students. New fancy programming languages have borrowed (copied, stolen? ... no, it is not bad) a lot of features from this two. You can prepare yourself for the future. Functional programming (style) is more important today and is introduced in imperative programming languages like C# (LINQ) or C++ (lambda) and many more. It is too bad that some students are learning Java only.

Usually the itch behind this question is "What buzzwords can I put on my resume that will land me the most lucrative/interesting/challenging/easy jobs ?". Though the question has merits as most resume are first screened by HR people that hat no comprehension of what they are looking for. but it is very shallow, as once you have passed the gates you need to deliver the goods.

It's not what languages you know that make you a good or bad programmer, it's how you can use it. For this there are basically two categories of programmers :

The ones that concentrate on learning a language to it's core. The most important is the language and how to use it. At extremes they tend to super optimize every little speck of code and will often use obscure features just because they can.

Then there are the ones that want to learn about techniques and paradigms. What language they use does not really matter so long as it can express their mental picture elegantly. At extremes these will tend to use UML or other such systems hoping others will do the grunt work of coding it.

In my opinion you need both. # 1 will provide short term skills and when wisely chosen will ease you through the HR gates but #2 will stay with you all your career and will define you as a programmer.

#2 will provide guidance and organize your train of thought towards a working solution to the problem at hand but without 1 it remains an idea, forever floating in the limbos of vaporware heaven (or hell depending on where you look at it from).

#1 will give you the means to implement ideas into real working systems but without 2 your systems will tend towards cancerous shapeless monsters.

Of real importance is to give students the opportunity to come into contact with several paradigms, the actual languages shouldn't matter.

Ofcourse, it is important to primarily teach those paradigms which give most work opportunities (probably OOP at this moment). Accordingly, it's also better to teach a broadly used language for this paradigm, as this is more useful than learning something you will likely never use. Therefore I also hated having to write pseudo code on my exams. Pseudocode is fine, as long as it doesn't have a 'fixed' syntax. You should just be able to bring concepts across.

So concretely:

OOP: .NET or Java

At least 1 additional programming paradigm, to make the student aware of other approaches.

Assembly language and microcode. A CS student should understand all the foundation layers of abstraction between boolean state machines and the latest high-level functional/OOP/etc. programming language paradigm.

Basic or Logo or Squeak (et.al.), if they ever want to be able to understand how to teach small kids some computer literacy.

Fortran, Cobol and Lisp, if they want to understand the history of programming languages, and what the actual problems are that modern practices fix.

Choosing 3 or more languages from different paradigms isn't that hard, many good answers have been given. But if I had to choose only one language, I'd go for Scala, because it's both functional and object oriented. You can explain and compare different approaches within the same language.

Don't forget the stack-oriented/concatenative languages! They can be real mind-benders. They emphasize building complexity using small, easy-to-understand primitives. You can use them to write pointfree (or tacit) code which feels so darn clean.

Despite its lack of mainstream-ness, I find that D, specifically version 2, provides some interesting lessons that can't be easily learned elsewhere. It makes a more serious attempt than any other language I can think of to get imperative/procedural, object-oriented and functional programming to play nice with each other, and to allow programming at a very low level (pointers, manual memory management, inline assembly language) and a very high level (generic and generative programming) in the same language.

This is valuable because, rather than seeing paradigms in isolation as if they existed in different universes, you get to see the forest through the trees. You get to see the strengths and weaknesses of each paradigm at a fine grained level as you blend them into your programs. You get to see how major aspects of paradigms can be implemented in libraries in terms of lower-level code. The standard library module std.algorithm implements important functional programming primitives, yet is straight, simple D code with no magic. Similarly, std.range implements lazy evaluation, but again is fairly simple D code. You get to understand the costs involved in the primitives of each paradigm, because D's close-to-the-metal features make what's really going on under the hood relatively transparent. You can even write something low-level that looks like C, and then create a pretty, high-level interface to it, in the same language, with no magic glue layers getting in the way.

People in the field should be able to explain their ideas in a coherent, structured way without and framework- or syntax-specific jargon. I shouldn't have to know the difference between your square brackets and braces in order to understand your algorithm. I shouldn't need to know what ?? means, or what the grep switches are.

Write in in plain language, but structure and format it like code. Anyone can then implement it in whatever language they like.

edit: This answer is partly motivated by the inabililty of some programmers to write pseudocode.

"Just write the algorithm in
pseudocode"

"What's that?"

The benefits of pseudocode is that non-programming stakeholders can understand it. I'm not suggesting that you want BAs and users proofing your code, however it can help when a non-programmer has an understanding of the required algorithm. Psuedocode removes the need to explain for (int i = 0; i < j; i++) and what is essentially boilerplate jargon.

First of all, it's still used (widely used !), and not only for kernels. I'm currently maintaining a business application coded in C. So, even with pure and simple C, you still can get a job. In big companies, in industry, almost everywhere (but in web dev).

If you're going to work in a Unix / Linux environment, not knowing at least a bit of C is a bit like going shopping and not being able to read the prices on the tags.

Pointers ! Everybody should understand pointers (cf. Joel Spolsky). Plus, once you've grabbed the malloc concept, you know exactly what kind of things happen when you carelessly type a "new" in an OOP langage.

Most "popular langages" syntaxes derives from C.

Yes, it's not always clear. Yes, it's difficult to learn. Yes, strings are somewhat of a nightmare for the beginners. But programming is not always clear and is difficult to learn, and you'll really understand what is great about OOP when, after studying C, you try C++ and discover std::string.

Of course, one should know more than one language, and not only an old procedural language. But if I had to go on a desert island with only one compiler, I'd go with my good old gcc. You can understand high-level programming if you know about low-level programming. I think it's not true the other way around.

Some of the programming languages that applied to acquire general problem solving skills, and programming concepts are Logo and Karel, they should be taught before C/C++/Java/Lisp/PERL/Assembly/whatever programming paradigm.