Variables, Symbols, Strings
(define x (list + '+ "+"))
x ==> (#[procedure +] + "+")
((car x) 2 3) ==> 5
(eq? (second x) '+) ==> #T
(eq? (third x) "+") ==> #F
(eq? (third x) '+) ==> #F
Abstract Syntax
(define (make-binop op left right)
(list left op right))
(define (binop? expression) (pair? expression))
(define (binop.left binop) (first binop))
(define (binop.op binop) (second binop))
(define (binop.right binop) (third binop))
(make-binop '+ 5 10) ==> ?????
Concrete Expressions
(make-binop '+ 5 10)
; ==> (5 + 10)
(make-binop '* (make-binop '+ 3 7) 5))
; ==> ((3 + 7) * 5)
(make-binop '+ 'x 10))
; ==> (x + 10)
(make-binop '* (make-binop '+ 'x 7) 'y))
; ==> ((x + 7) * y)
Evaluating Expressions
(define (expression expr)
(cond ((number? expr) expr)
((symbol? expr) (variable.value expr))
((binop? expr)
(let ((op (binop.op expr))
(rand-1 (expression
(binop.left expr)))
(rand-2 (expression
(binop.right expr))))
(cond ((eq? op '+)
(+ rand-1 rand-2))
((eq? op '*)
(* rand-1 rand-2))
(else (error "Bad operator"
expr)))))
(else (error "Bad expression" expr))))
Abstract Syntax
;; Previous, "Infix" version
(define (make-binop op left right)
(list left op right))
(define (binop? expression) (pair? expression))
(define (binop.left binop) (first binop))
(define (binop.op binop) (second binop))
(define (binop.right binop) (third binop))
;; New, "Prefix" version
(define (make-binop op left right)
(list op left right))
(define (binop? expression) (pair? expression))
(define (binop.left binop) (second binop))
(define (binop.op binop) (first binop))
(define (binop.right binop) (third binop))
(make-binop '+ 5 10)) ==> ????
Variables and Lookup
(define (assq name a-list)
;; A-List looks like
;; ((name1 ...) (name2 ...) ...)
(cond ((null? a-list) #F)
((eq? name (first (car a-list)))
(car a-list))
(else (assq name (cdr a-list)))))
(define (variable.value name)
(let ((entry (assq name variables)))
(if entry
(cdr entry)
(error "No such variable" name))))
List of Operators
(define (expression expr)
(define operators
(list (cons '+ +)
(cons '* *)))
(cond ...
((binop? expr)
(let ((op (binop.op expr)) ...)
(let ((procedure (assq op operators)))
(if procedure
((cdr procedure) rand-1 rand-2)
(error "Bad operator" expr)))))
...))
Are Operators Just Variables?
(define variables
(list (cons 'X 3)
(cons 'Y 5)
(cons '+ +)
(cons '* *)))
(define (expression expr)
(cond ...
((binop? expr)
(let ((op (binop.op expr)) ...)
(let ((procedure (variable.value op)))
(procedure rand-1 rand-2))))
...))
Data Abstraction: Bane or Boon?
(define make-var cons)
(define var.name car)
(define var.value cdr)
(define (variable.value var)
(define (loop vars)
(if (null? vars)
(error "Undefined variable" var)
(let ((first-var (first vars)))
(if (eq? var (var.name first-var))
(var.value first-var)
(loop (cdr vars))))))
(loop variables))
(define (variable.value name)
(let ((entry (assq name variables)))
(if entry
(cdr entry)
(error "No such variable" name))))