For one reason or another, I haven't been teaching functional programming at Kent for a few years, so it's interesting to be back doing it, and to reflect on that.
The last time I was involved was when we were teaching Haskell in the first year, starting in the second term, and following up on Java which had been taught from the start. We came to the conclusion that this wasn't ideal: instead of reinforcing each other, it seemed perverse to start with a second paradigm before the first one was properly internalised. This time I'm teaching in the second term of the second year … just like we did twenty years ago, in fact … and it seems to be going much better.
One thing that's really helpful is to be able to discuss features of Haskell using Java as a reference point. For example, what does it mean to belong to a class? Well, you have to implement the interface that's given by the class declaration. Seems to demystify the idea.
Sometimes Haskell is so much better: data types with multiple constructors (e.g simple geometric shapes such as circles and rectangles) just work in Haskell. No ugly abstract base classes and subtyping, no problem with binary methods, the joys of pattern matching … great stuff.
Types play an important role: the first and most important piece of documentation for any function, but also a way of discovering things in the library thanks to hoogle. If you've not tried this out, give it a go: it works for monotypes, such as Char -> Bool, just as much as for complicated polymorphic examples. Really useful, and appreciated by the students.
On the other hand, some things are difficult for the beginner. It's too easy to overlook concrete syntax when you understand it well - indeed the whole point is that the syntax almost disappears, and you perceive the intention, or the semantics immediately - but that's just not the case for beginners, and the novelty of the Haskell syntax can be a problem. Just function application looks unfamiliar, and the layout sensitivity can trip people up too. Other little irritations: length (of a list) returns a fixed size Int, as does replicate: we should probably use the generic versions from scratch and ignore Int altogether?
Funny things you wouldn't think of. A colleague sitting in on the lectures noted that the (x:xs) notation could be a problem: sometimes it wasn't clear when I was saying "x is" and when I was saying "exes". Perhaps I need to say "excess" instead, or maybe ditch that notation altogether?
I've been lucky enough to have inherited Olaf Chitil's slides (though I think some of my DNA is in there from a number of generations back) which are great. The problem is I'm never happy with using someone else's slides - or indeed my own from a previous year - so start rewriting them. Even when this is the last time they will be used, because next year we're trying something different …
As a root and branch curriculum review we looked at what we taught in the second year of our programmes as core material, and found that we wanted to include about 180 credits worth of material in a 120 credit year. Together with all the other material we saw as core, we wanted to carry on teaching functional programming, and also to teach concurrency (which we currently do in occam-pi, optionally to second and final years), but we didn't have enough time to teach two separate languages. So, we decided to use a language with both: that could be Clojure, we could look at Haskell's various concurrency extensions, but we'll be working with Erlang next year.
Not everyone was happy with this … indeed I'm not 100% sure … but it will be really interesting to look at Erlang as a practical functional/concurrent language, and use it as a base for exercises and projects, as well as a comparison point for other approaches like Haskell, occam-pi. I'll report back in a year's time …