Tuesday, August 3, 2010

Writing a Scala Textbook

So this coming fall I am going to be teaching the CS1 course at Trinity (CSCI 1320) using Scala. This is part of an experiment we are conducting to see how we might want to change the languages used in our introductory sequence. One of the challenges in using Scala is that there really aren't that many resources currently out for the language and none that work as a textbook for new programmers. All the current material assumes that students know how to program in one or more other languages and then builds on top of that. To address this, I am writing my own materials going into the beginning of the semester.

I have done this previously for Java with our CS2 (CSCI 1321) and CS0.5 (CSCI 1311), the latter using Greenfoot which also didn't have an existing text when I started using it. In some ways, the topics of introductory CS are the same no matter what language you use. However, the nature of the language can alter the ideal way to present information.

As it stands, we intend to keep our CS1 as a normal introduction to programming. We don't want this to be an objects-first type of class. The second semester will get into OO. The first semester is just about building logic and figuring out how to break programs down and use a programming language to construct solutions. So while Scala is 100% OO, that isn't being stressed early on. The functional aspects can be stressed early on.

Indeed, it is the more functional side that convinced me that Scala was worth trying to a CS1 course. Scala has a REPL and allows writing scripts. It works very well for programming in the small. However, unlike normal scripting languages, Scala is statically typed so students get to learn about types and see compile time error messages. Indeed, I'm hoping to run the class very much like what I have done in C for the last decade or so. We will work in Linux with the command line. They will edit scripts with vi. Unlike C, they can use the REPL to test out little things or load in the code from files instead of running them as standalone scripts.

Using Scala as the language though does change some aspects of what I see as the optimal order of presentation. It also adds richness to certain other topics. The big ones I've run into so far are functions and collections. Normally I do my introduction to Linux and the basics of C. Then I talk about binary numbers. That is followed by sequential execution, functions, conditional execution, and recursion. After that will come loops and arrays. In Scala, the functions aspect gets richer because it is a functional language. It has function literals that can be created on the fly. It is possible to easily pass functions as arguments and return them. In C, function pointers and void* were about the only topics I didn't cover. Those same ideas will be covered in Scala and early on because they are a lot smoother.

The biggest change so far though is where I am doing "arrays". In C there wasn't really any point introducing arrays until you had loops. You simply couldn't do much with an array without a loop. That isn't true in Scala. Collections in Scala, be they arrays, lists, whatever, have a rich set of methods defined for them. Indeed, the Scala for loop does nothing more than translate to calls of these other methods. So in Scala the logic goes the other way. Because they know functions, it makes sense to introduce collections and talk about the methods like map, filter, and reduce. Once those have been covered, then we talk about loops and see how they provide us with a nicer way to write a lot of the iteration behavior that we had done before using either recursion or higher order functions on collections.

One thing that I haven't figured out exactly how to include is Ranges. These are really significant in for loops. If you just want to have a counting for loop in Scala you would write for(i <- 1 to 10). The 1 to 10 creates a range which is an iterable over exactly those values. They have a lot more power too. The question is, do they go in the chapter on collections or in the chapter on loops with the for? The chapter on collections is already going to have quite a bit in it and right now I was planning to cover only arrays and lists. Those are basically the most fundamental mutable and immutable collections respectively. The range almost seems out of place at that point and it opens up a whole big area of the fact that there are a lot of other types of iterables, sequences, etc. in Scala. That will have to get opened at some point though. The question is whether to do it with the other collections or wait until they are really needed with the for loop.

If anyone has suggestions on this, please post a comment. One thing I would point out is that higher order functions on ranges can be fun to play with as well. The for loop isn't really needed. To see this, just consider the following definition of factorial for positive numbers.

def fact(n:Int) = (1 to n).product

So the range isn't just for counting in a loop. That just happens to be the wa most people will use it by default.