Friday, July 30, 2010

Teaching programming

I taught a second year course on Java programming last semester, and, being in a university (and being a programming languages person), I think about teaching programming a fair bit. In particular, which languages should we teach?

Here is how I would design a curriculum if I were king (or head of programme or whatever):

1st year: assembly (8086, none of this RISC crap) and Haskell in parallel (in fact I would start with machine code and lambda calculus for the first few weeks).

2nd year: C and Python, again in parallel

3rd year: C++ and Java.

You could swap Haskell for some other pure, lazy, functional language if you like, and Javascript, Ruby, or Perl for Python, and Java for C#, and you probably don't need C++ and Java in the third year, one or the other would do.

And of course, this wouldn't work in real life --- you would scare off most of the students in the first year and it would only appeal to the very smartest and geekiest of students. But I think it is a good order: students would get some key concepts (recursion, pointers, machine organisation) early which they can apply when the learn the later langauges. The problem with learning Java first and then the fun stuff, is you don't learn your lessons that way - programming in C helps to make you a better Java programmer, but not vice-versa.

I think this organisation would give a good appreciation of real-life computers (too many students have no idea about how their Java programs relate to bits and bytes); and how to think about programming in a 'smart' way (higher order functions etc.)

A final advantage, the languages match the scale of the exercises: small programs in assembly/Haskell up to large programs in Java, just the way it was all designed.

I honestly think this would be the best way of teaching programming to good students. Unfortunately, a CS degree is about more than just programming, and students get a say in how they are taught, so it will never catch on.

8 comments:

Anonymous said...

Asked a fun question to my honours class today: why can't you have a double-linked list if you're reference counted. (There was a comment to this effect in some C++ code used as an example of the Iterator pattern).

Noone could (or bothered?) to answer it - so I did it worked on the board. Interesting that this question really is more subtle than I'd first thought: and for people raised on Java - even Java with (I hope!) a fair bit of C/C++ - seeing the answer isn't intuitive.

but then I guess I wrote a book about this once...

Alex Buckley said...

1st year: Scheme.
2nd year: Java and x86.
3rd year: C/C++ and HTML5+Javascript.

Nick Cameron. said...

Alex - why?

Is Scheme so they know how to use brackets properly before they get to 2nd year? Because I can't think of any other reason to teach it.

Shouldn't you be pushing something like

1st year: Java
2nd year: Java
3rd year: Java

John Tang said...

nice- makes sense to build up from lambda calculus (chris clacks' course was really good!) to OO programming, but I would move python to the third year as students would get too used to dynamic typing, which makes C/C++/java look like they are from the dark ages, especially since most courses don't touch on performance issues.

Also, although I agree that java doesn't make you a better C "programmer", it does make you a better "software engineer", which is what most CS grads end up doing.

Nick Cameron. said...

Hi John, I like Python before Java, hopefully they'll ahve learned static typing from Haskell in the 1st year and then C. They should also get some motivation for static types, because writing large-ish Python programs can be painful.

I guess this is a curriculum for programmers rather than software engineers. But, I don't think being a Java programmer makes you a better software engineer in C. You need to be good at non-OO software engineering for that.

Also, Java, C, and C++ _are_ from the dark ages, PL-wise. It would be a good thing if a few more graduates realised that!

Sophia Drossopoulou said...

Why does the functional language have to be lazy? And what about Prolog?

Sophia Drossopoulou said...

> I don't think being a Java programmer makes you a better software engineer in C

I think that being a good software engineer is orthogonal to the language employed, but that OO languages help you understand the concerns of software engineering.

Toon Verwaest said...

I was taught Scheme as a first language and I am quite sure it was the best possible choice for me.

It's exactly for the opposite reason as what you said: syntax isn't relevant; you rather focus on the semantics. Everything looks the same and can be exchanged everywhere. You don't need to think about operator precedence because the brackets enforce order.

And then the most important part is that the language forces you to work with lambdas and only lambdas. When I started working at a Java-taught institution I noticed that even students in the third year and higher still didn't know the difference between static and dynamic scoping! This is something I learned in the second month or so.

Scheme can teach you OO from the ground up using lambdas (dispatch objects). Since there is no magic in the language that makes it work, but you rather construct your own objects, this made it really clear to me how it all fitted together.

Scheme is maybe not the only language that could teach all of this, but I haven't really seen other languages (and other environments than Racket Scheme, PLT) that easily support such coding from the ground up. And especially in Racket the Help Desk with its links really helps you out. Probably not a merit of Scheme on its own; but then again, most people probably use Java for Eclipse.

Too bad there is no Smalltalk in any of those lists though ;)