The idea that programs are lists makes Lisp well-suited to meta-programming---programs that modify other programs. For this reason, Lisp dialects are popular among AI researchers.
Here are some simple examples of programs as data: to prevent evaluation of any expression, you can simply put a single quote in front of the expression:
; Evaluate list data as if it were an expression in the-environment (eval (list '+ 1 2 3) (the-environment)) ; A single quote recursively prevents evaluation of sublists (define mystuff '(* (+ 1 2) 3))
The following code implements a simple constraint solver. A constraint solver is a program to which you can feed constraints on variables---and the solver will compute all satisfying assignments of values within some domain.
; Replaces all occurrences in alist of sym with replacement. (define (replace-sym sym replacement alist) (if (null? alist) () (let* ((current (car alist)) (replaced-current (cond ((symbol? current) (if (eq? sym current) replacement current)) ((list? current) (replace-sym sym replacement current)) (else current)))) (cons replaced-current (replace-sym sym replacement (cdr alist)))))) ; A function that replaces varname with each of nums, then evaluates ; the constraint under that substitution. All satisfying numbers are ; returned as a list (define (try-nums varname nums constraint) (if (null? nums) () (let* ((num (car nums)) (rest (cdr nums)) (rest-result (try-nums varname rest constraint)) (substituted (replace-sym varname num constraint))) (if (eval substituted (the-environment)) (cons num rest-result) rest-result)))) (define my-constraint '(and (> x 3) (< x 9) (> (/ x 2) (- x 4)))) (define digits '(0 1 2 3 4 5 6 7 8 9)) (try-nums 'x digits my-constraint)
The last line prints (4 5 6 7), which are all values which satisfy my-constraint with respect to x. Notice that we did not have to write code explicitly to evaluate this constraint---instead, we replace the variable with the value, using replace-sym, and use the eval function.
Note: I don't necessarily expect you to understand this code. I had some empty space on my handouts, so I filled it; some of you may have fun figuring this program out.