Lecture 01

For next time:

    1. Sign up for the class mailing list and (optionally) the CS @ Olin mailing list.

    2. Get the book(s).

    3. Read Louden, Programming Languages, Chapter 1, Sections 1.1 through 1.3 and answer the reading questions below.

    4. Do the Warmup exercises in Homework 1.

What is this class about?

Programming paradigms

1) functional programming in Scheme

2) logic programming in Prolog

Automata

1) regular expressions and finite automata

2) context-free grammars and pushdown automata

Theory of computation

1) Turing machine

2) decidability

Complexity

1) analysis of algorithms

2) P and NP

3) Incompleteness

Algorithms and data structures

1) especially tree-shaped structures and computation

Language translation

1) parsing

2) maybe code generation

Skills

1) polyparadigmatic thinking

2) practical language design and translation

3) algorithmic thinking

4) proof design

5) theory appreciation

Scheme syntax

[Note: this presentation follows Abelson and Sussman, Structure and Interpretation of Computer Programs.

You might prefer to read The Racket Guide.]

Numbers are primitive expressions.

Standard arithmetic operators are built in: +-*/

Applying operators to operands looks like this:

(+ 1 2)

The parentheses are not decorative; they are the "apply" operator.

+ 1 2

is just a sequence of three values.

This placement of the operator is called prefix, as opposed to infix and postfix.

Do you know languages/contexts that use infix? postfix?

What are the pros and cons of each?

This is a small example of a kind of discussion I want us to have:

1) map out the space of possible designs by exploring endpoints

2) understand tradeoffs in the space.

Compound expressions

An advantage of Scheme syntax is that the meaning of an expression is unambiguous.

In "normal" notation, what does 1 + 2 * 3 mean?

What are the two possibilities?

How do you represent the possibilities?

How do you know which one is right?

Draw a tree that represents this compound expression:

(* (+ 2 (* 4 6))

(+ 3 5 7))

Evaluating expressions

Here is Racket syntax in BNF:

expr› ::= ‹id

| ( ‹expr›+ )

| ( lambda ( ‹id›* ) ‹expr› )

| ‹val

val› ::= ‹number› | ‹primop

id› ::= any name except for lambda

Where ::= is pronounced "can be" and | is pronounced "or".

An expression can be

1) An identifier,

2) One or more identifiers in parens,

3) A lambda expression, or

4) A value.

That's pretty much it.

Variable binding

define is an operator that creates a binding between a name and a value

(define pi 3.1415926535897931)

Now the expression

pi

has the value 3.1415926535897931

This is not the same as an assignment statement in an imperative language, because you cannot rebind a name.

An environment is a set of bindings.

Procedures

A procedure is an object* that represents a function.

[*LISP/Scheme programmers probably wouldn't call it that.]

There are two ways to create a procedure. One is the lambda operator

(lambda (x) (+ x 1))

The value of this expression is an object that represents the function SUCCESSOR.

(lambda (y) (+ y 1))

The value of this expression is an object that _also_ represents the function SUCCESSOR. So these two procedures are equivalent.

You can bind a name to a procedure.

(define square (lambda (x) (* x x)))

But this sort of thing happens so often that there is a simplified syntax, also known as 'syntactic sugar':

(define (square x)

(* x x))

If you are used to languages with a return statement, this might seem odd. All procedures contains a single expression; the 'return value' is the value of that expression.

Write a procedure, (sum-of-squares), that takes two arguments and uses (square) to compute their sum of squares.

Reading questions

Louden, Programming Languages, Chapter 1, Sections 1.1 through 1.3

1) The first sentence of the chapter is a statement of what famous hypothesis in linguistics?

2) What are the elements of the von Neumann model of a computer?

3) What is Church's thesis? You might want to read the Wikipedia page, too.

4) Louden claims that one of the necessary features of a programming language is that it be machine-readable. Can you think of some limitations this requirement puts on programming languages?

5) In the context of data, give an example of a basic abstraction, a structured abstraction and a unit abstraction.

6) In the context of control flow, give an example of a basic abstraction, a structured abstration and a unit abstraction.

7) In Louden's vocabulary, what's the difference between a procedure and a function?

[The paragraph in the middle of page 1-9 is important.]

8) What are the 3.5 programming paradigms?

9) What is the lambda calculus?

10) What does it mean to say that a language is Turing complete?

11) What is a very high level language?