CSE341 Notes for Wednesday, 9/30/09

I spent some time discussing my vision for the course. I mentioned that the great language wars have a long history in the computer science community.

I discussed a table of some of the major programming languages and approximately when they were invented:

+-----------------+-----------------+-----------------+----------------------+
| 1960            | 1970            | 1980            | 1990             2000|
+-----------------+-----------------+-----------------+----------------------+
| Fortran         |                 |                 | Matlab               |
+-----------------+-----------------+-----------------+----------------------+
| Cobol           | DBMS's          | SQL             | VB                   |
+-----------------+-----------------+-----------------+----------------------+
| Lisp            |         Scheme  | ML              |                      |
+-----------------+-----------------+-----------------+----------------------+
| Algol           | Pascal Smalltalk| Ada             |         Java     C#  |
|                 | C               | C++             |                      |
+-----------------+-----------------+-----------------+----------------------+
|         BASIC   |                 |         Perl    | Python  Ruby         |
|                 |                 |                 |         Javascript   |
|                 |                 |                 |         PHP          |
+-----------------+-----------------+-----------------+----------------------+
|                 | Prolog          |                 |                      |
+-----------------+-----------------+-----------------+----------------------+
I also mentioned that one of the major divisions predates computers. As far back as 1936 we had Alan Turing in England writing a paper about something called a Turing Machine that computes things by reading symbols from a tape and, depending upon the symbols, potentially writing new symbols to replace the old ones (something we call mutable state). Across the Atlantic that same year we had Alonzo Church at Princeton exploring the properties of functions and inventing something called the lambda calculus to characterize computation in a different way. The Turing approach inspired people to develop procedural languages like C, C++ and Java and the Church approach led people like John McCarthy to invent programming languages like Lisp (the first of the functional programming languages).

You are probably more familiar with the languages that grew out of the procedural approach because they are more often used in industry. But you've probably at least heard about some of the functional languages because they have loyal fans and they are used extensively in certain branches of computing like artificial intelligence. We will be studying two functional languages: ML, which is quite different from Lisp, and Scheme, which is a descendant of the original Lisp.

Some people wonder why we don't spend more time covering popular programming languages like C++. The problem with C++ is that it's not different enough from Java to be worth studying. It would be like taking a field trip to Spokane to find out how other people live. If we're going to stretch your minds, we need to travel to places like Tokyo and Beijing to see very different ways of living. I mentioned that in the computer science community the divide between functional programming and procedural programming is similar to the cultural division between East and West. So think of this course as your foreign language requirement or your overseas studies opportunity.

One final point I made is that even if some of the languages we study are not the most popular languages in industry, they still affect the lives of all programmers because they influence other languages. Java, for example, was designed by Jim Gosling but its development has also been influenced by Guy Steele. Steele has been at Sun since 1994, but prior to that he was the coinventor of Scheme with Gerry Sussman.

I then switched to the ML interpreter where you can type in expressions and see how the interpreter responds. This kind of interaction is known as a repl (Read/Eval/Print Loop). It was pioneered by the functional camp but the approach is now common. For example, both Python and Ruby have similar environments and even Java has a primitive form of this in the interactions pane of the DrJava programming environment (developed by another fan of functional programming called Corky Cartwright who teaches at Rice). I pointed out that it is very important when working with the SML environment to pay close attention to the type information it gives you as you enter various expressions.

We then explored how to define functions in ML and I demonstrated the more usual interaction with the ML interpreter where we edit a file of ML definitions in one window and in the other window we keep restarting ML and loading in the new version of the definitions.

First I discussed some basic functions using type notations for the function arguments:

        fun inc(n : int) = n + 1;
        fun sqr(n : real) = n * n;
I pointed out that ML cares a lot about the types of various program elements, but it uses type inference to deduce the types when it can. For example, the inc function above doesn't need the type specification because of the constant 1:

        fun inc(n) = n + 1;
When we changed the 1 to 1.0, we found that ML correctly identified this as a function that takes a real and returns a real. I tend not to include type specifications unless I need to. But what happens when there isn't a value like 1 or 1.0 to make the type clear, so I typed in this function:

        fun sqr(n) = n * n;
The issue is that multiplication is overloaded with integer multiplication and real multiplication. Some people thought this would produce an error and that's what it did in the older versions of ML. ML 97 instead defaults to type int. So if we wanted a function for squaring reals, we'd have to include a type specification. One interesting aspect of ML is that you can specify that type in many different ways. For example, you can say that the parameter is of type real anywhere the parameter is mentioned:

        fun sqr(n:real) = n * n;
        fun sqr(n) = (n:real) * n;
        fun sqr(n) = n * (n:real);
Or you can say that the function result is real:

        fun sqr(n) = ((n * n) : real);
At this point I switched to using two windows. In one window I ran the emacs editor to edit a file of definitions. In the other window I ran the sml environment to load and execute the definitions. This is the way most people use ML. You can use any editor you like for creating the files. We saw that you can load the definitions in the interpreter by giving a command like this:

        use("wed.sml");
I mentioned that it's in some ways easier to exit the interpreter every time and execute a command like this at the command prompt:

        sml wed.sml
This is particularly easy when you're working with the same file repeatedly. You have to type the command above the first time you want to use the file, but then you can get by with three keystrokes. Type ctrl-d to exit ML. Then type the up-arrow key to get back this command. Then type enter to execute it. An added benefit is that it starts you with a fresh version of the ML environment each time.

Then we talked about using recursion to define functions. I mentioned that the functional languages use recursion often, so if you haven't yet mastered it, this will be your chance to finally figure it out.

For our recursive definitions, we'll need to use the if/else construct, which has the following general form:

if <boolean expression> then <expression> else <expression> The first example we looked at is a factorial function:

        fun factorial(n) =
            if n = 0 then 1
            else n * factorial(n - 1)
Then we looked at an example of list recursion. We wrote this code to find the last element of a list:

        fun last(lst) =
            if length(lst) = 1 then hd(lst)
            else last(tl(lst))

Stuart Reges
Last modified: Wed Sep 30 18:29:06 PDT 2009