CSE413 Notes for Wednesday, 1/3/24

I spent some time discussing the syllabus and 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        2015|
    +--------------+--------------+--------------+--------------+-----------------+
    | Fortran      |              | Matlab       | R            |                 |
    +--------------+--------------+--------------+--------------+-----------------+
    | Cobol        | DBMS's       | SQL          | VB  MySQL    |                 |
    +--------------+--------------+--------------+--------------+-----------------+
    | Lisp         |      Scheme  | ML   Miranda | Haskell OCaml|                 |
    +--------------+--------------+--------------+--------------+-----------------+
    | Algol        | Pascal       | Ada          | Java  C#     |                 |
    |              | C            | C++          |              |            Rust |
    +--------------+--------------+--------------+--------------+-----------------+
    |              |    Smalltalk |  Objective C |              |           Swift |
    +--------------+--------------+--------------+--------------+-----------------+
    |      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: OCaml, 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 joined Sun Microsystems in 1994 (later acquired by Oracle), but prior to that he was the coinventor of Scheme with Gerry Sussman.

I spent the rest of the class in the OCaml interpreter typing in expressions and seeing 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 Java added one called JShell starting with Java 9. I pointed out that it is very important when working with the OCaml environment to pay close attention to the type information it gives you as you enter various expressions.

We looked at several kinds of data:

Tuples provide a way to glue together several pieces of data, not necessarily of the same type. Notice that we use parentheses for tuples and separate values with commas. Lists provide a way to have a sequence of data all of the same type. Notice that we use square brackets for lists and separate values with semicolons.

We saw that OCaml had the usual arithmetic operators for integers that we expect from Java (+, -, *, /, mod). We found that you can't mix integers and floats easily. There are parallel operators for floats that end in period (+., -., *., /.). There are functions for converting from one type to another like float_of_int, int_of_float, and string_of_int.

Each OCaml program consists of a series of bindings. You bind an identifier to a value with a "let" definition:

        let x = e
OCaml uses the current set of bindings to evaluate the expression on the right and adds a new binding for the identifier on the left, as in this definition of a variable:
        let a = 2 + 3 * 9
This binds the variable a to the value obtained by evaluating the right side (29 of type int).

We also defined a few functions this way, as in:

        let double(n) = 2 * n
This defines a function called double that returns twice the value passed to it as a parameter. I said that we would spend a lot of time in the next lecture discussing how to define functions.

We saw that in the top level OCaml environment we had to include two semicolons at the end of an expression to get OCaml to evaluate the expression. These semicolons are only needed in the interpreter. They are not part of the language.

I said that in the next lecture we would practice the more normal use of the interpreter where we have two windows, one for editing and one for the interpreter.


Stuart Reges
Last modified: Tue Feb 13 10:33:18 PST 2024