CS217 Day 1 Monday, March 27, 2000

We will be studying programming languages using the programming language Scheme as a tool. Issues include Scheme is a dialect of Lisp, but it's block structure and lexical scope make it a descendent of Algol, along with Pascal and Ada.

We will use Scheme to study the meaning of programming language constructs by building interpreters to implement them.
We will be writing Scheme programs that operate on defined programs.

The meaning of programs in a defined language will be defined relative to the meaning of programs in Scheme.

Therefore we need to learn the syntax and semantics of Scheme and become proficient in its use.

Data types in Scheme include BNF (Backus-Naur Form) specification of Scheme data:
[x] -- the syntactic category x. (Angle brackets don't show in HTML.)
| -- alternative
::= -- can be
{...}* -- zero or more of ...
{...}+ -- one or more of ...
Other symbols are terminal symbols
    [list]         ::=  () | ([datum] . [list])
    [dotted-datum] ::= ([datum] . [datum])
or
    [list]         ::= ({[datum]}*)
    [dotted-datum] ::= ({[datum]}+ . [datum])

    [vector]       ::= #({[datum]}*)
    [datum]        ::= [number] | [symbol] | [boolean] | [string]
                     | [list] | [dotted-datum] | [vector]

There are many procedures for manipulating, constructing, recognizing, converting Scheme data.
E.g.
    (+ e0 ...) => the sum of the (numerical) values of e0, ...
    (* e0 ...) => the product of the values of e0, ...

    (number? e0) => #t if e0 evaluates to a number, otherwise #f
    (symbol? e0) => #t if e0 evaluates to a symbol, otherwise #f

    (car '(a . b)) => a
    (cdr '(a . b)) => b
    (cons e f) => (a . b), where e => a and f => b

    (caar '((a . b) . c)) => a
    (cdar '((a . b) . c)) => b
    (cadr '(a . (b . c))) => b
    (cddr '(a . (b . c))) => c

    (list e0 ...) => (a0 ...), where ei => ai
    (vector e0 ...) => #(a0 ...), where ei => ai

    (list->vector '(a0 ...)) => #(a0 ...)
    (vector->list #(a0 ...)) => (a0 ...)

    (list-ref '(a0 ...) i) => ai
    (vector-ref #(a0 ...) i) => ai

    (set-car! '(a . b) e) replaces a with the value of e
    (set-cdr! '(a . b) e) replaces b with the value of e
    (vector-set! #(a0 ...) i e) replaces ai with the value of e

Expressions in Scheme include

Two expecially expecially useful procedures: map and apply.
    (map p (e1 ...))
=>
    (list (p e1) ...)
    a list of the values of p applied to e1, ...


    (map p (e1 ...) (f1 ...))
=>
    (list (p e1 f1) ...)
    a list of the values of a two arg procedure p

    (apply p (a1 ...))
=>
    (p a1 ...)
    the value of p applied to a1, ...
E.g.
    (map (lambda (x) (* x x)) '(1 2 3)) => (1 3 9)
    (map + '(1 2 3) '(10 20 30) '(100 200 300)) => (111 222 333)

    (map car '((a 1) (b 2) (c 3))) => (a b c)
    (map cdr '((a 1) (b 2) (c 3))) => ((1) (2) (3))
    (map cadr '((a 1) (b 2) (c 3))) => (1 2 3)
    (map cons '(a b c) '(1 2 3)) => ((a 1) (b 2) (c 3))

    (apply + '(1 2 3) => 6
    (apply (lambda (x y z) (cons z (list y x))) '(1 2 3) => (3 2 1)

    (apply + (map + '(1 2 3) '(10 20 30))) => 66

    (apply car '(a b c)) => a
    (apply cdr '(a b c)) => (b c)
    (apply cons '(a b)) => (a . b)

Example definitions

-- A procedure that appends two lists

    (define append
      (lambda (lst1 lst2)
        (if (null? lst1)
            lst2
            (cons (car lst1) (append (cdr lst1) lst2)))))
-- Procedures that reverse the members of a list.
    (define reverse1
      (lambda (lst)
        (if (null? lst)
            '()
            (append (reverse1 (cdr lst)) (list (car lst))))))

    (define reverse2
      (lambda (lst)
        (letrec ((rev-helper (lambda (lst1 lst2)
                               (if (null? lst1)
                                   lst2
                                   (rev-helper
                                     (cdr lst1)
                                     (cons (car lst1) lst2))))))
          (rev-helper lst '()))))
Running Scheme within Emacs Read TSPL Ch2 and EOPL 1.1. Start work on Assignment 1.