Section 10: LISP to Scheme

Evolution of Software Languages

Theo D'Hondt

Bachelor of Computer Science Faculty of Sciences and Bio-Engineering Sciences Vrije Universiteit Brussel Academic Year 2015-2016

Evolution of Software Languages 1 10: LISP to Scheme John McCarthy

• Father of LISP • Credited with term "AI" • Built on the IBM 604/9 • Originated at MIT and at

http://www.independent.co.uk/news/obituaries/ Stanford john-mccarthy-computer-scientist-known-as-the- father-of-ai-6255307.html • Survives in • Gave rise to Scheme • First "functional" language

Evolution of Software Languages 2 10: LISP to Scheme John McCarthy

Lispers say these are LISP... Arc, AutoLISP,• Father , of LISP Common Lisp, • Credited Lisp, EuLisp, with termFranz "AI" Lisp, , ,• Built on ISLISP, the IBM LeLisp, 604/9 LFE, ,• Originated MDL, Newlisp, at MIT NIL, and at http://www.independent.co.uk/news/obituaries/ Stanford john-mccarthy-computer-scientist-known-as-the- father-of-ai-6255307.htmlPicolisp, , Racket, RPL,• Survives Scheme, in Common SKILL, Lisp Spice• Lisp,Gave , rise Zetalisp to Scheme • First "functional" language

Evolution of Software Languages 3 10: LISP to Scheme LISP I Programmer's Manual (March 1960)

Define a function collapse:

given some implementation for a function append:

Evolution of Software Languages 4 10: LISP to Scheme LISP I Programmer's Manual (March 1960)

Define a function collapse: resulting in the input card deck

given some implementation for a function append:

Evolution of Software Languages 5 10: LISP to Scheme (pre-) Common Lisp

• S-expressions • Functions as values • Meta-circularity • Quoting and eval • Automatic garbage collection • Full syntactic macros • (later) CLOS and MOP • Encourages imperative style • Ambivalent view on functions/function values • Ambivalent view on scoping • No optimisation • No full

Evolution of Software Languages 6 10: LISP to Scheme (pre-) Common Lisp

• S-expressions • Functions as values • Meta-circularity • Quoting and eval • Automatic garbage collection • Full syntactic macros • (later) CLOS and MOP • Encourages imperative style • Ambivalent view on functions/function values • Ambivalent view on scoping • No tail call optimisation • No full continuations

https://en.wikipedia.org/wiki/Symbolics Evolution of Software Languages 7 10: LISP to Scheme (pre-) Common Lisp

• S-expressions • Functions as values • Meta-circularity • Quoting and eval • Automatic garbage collection • Full syntactic macros • (later) CLOS and MOP • Encourages imperative style • Ambivalent view on functions/function values • Ambivalent view on scoping http://www.computerhistory.org/ revolution/artificial- • No tail call optimisation intelligence-robotics/13/290/1254 • No full continuations

https://en.wikipedia.org/wiki/Symbolics Evolution of Software Languages 8 10: LISP to Scheme LISP example1 (defparameter *width* 100) (defparameter *height* 30) (defparameter *jungle* '(45 10 10 10)) (defparameter *plant-energy* 80)

(defparameter *plants* (make-hash-table :test #'equal))

(defun random-plant (left top width height) (let ((pos ( (+ left (random width)) (+ top (random height))))) (setf (gethash pos *plants*) t)))

(defun add-plants () (apply #'random-plant *jungle*) (random-plant 0 0 *width* *height*))

(defstruct animal x y energy dir genes)

(defparameter *animals* (list (make-animal :x (ash *width* -1) :y (ash *height* -1) :energy 1000 :dir 0 :genes (loop repeat 8 collecting (1+ (random 10))))))

http://landoflisp.com/source.html Evolution of Software Languages 9 10: LISP to Scheme LISP example2 (defun move (animal) (let ((dir (animal-dir animal)) (x (animal-x animal)) (y (animal-y animal))) (setf (animal-x animal) (mod (+ x (cond ((and (>= dir 2) (< dir 5)) 1) ((or (= dir 1) (= dir 5)) 0) (t -1)) *width*) *width*)) (setf (animal-y animal) (mod (+ y (cond ((and (>= dir 0) (< dir 3)) -1) ((and (>= dir 4) (< dir 7)) 1) (t 0)) *height*) *height*)) (decf (animal-energy animal))))

(defun turn (animal) (let ((x (random (apply #'+ (animal-genes animal))))) (labels ((angle (genes x) (let ((xnu (- x (car genes)))) (if (< xnu 0) 0 (1+ (angle (cdr genes) xnu)))))) (setf (animal-dir animal) (mod (+ (animal-dir animal) (angle (animal-genes animal) x)) 8))))) Evolution of Software Languages 10 10: LISP to Scheme LISP example3

(defun eat (animal) (let ((pos (cons (animal-x animal) (animal-y animal)))) (when (gethash pos *plants*) (incf (animal-energy animal) *plant-energy*) (remhash pos *plants*))))

(defparameter *reproduction-energy* 200)

(defun reproduce (animal) (let ((e (animal-energy animal))) (when (>= e *reproduction-energy*) (setf (animal-energy animal) (ash e -1)) (let ((animal-nu (copy-structure animal)) (genes (copy-list (animal-genes animal))) (mutation (random 8))) (setf (nth mutation genes) (max 1 (+ (nth mutation genes) (random 3) -1))) (setf (animal-genes animal-nu) genes) (push animal-nu *animals*)))))

Evolution of Software Languages 11 10: LISP to Scheme LISP example4 (defun update-world () (setf *animals* (remove-if (lambda (animal) (<= (animal-energy animal) 0)) *animals*)) (mapc (lambda (animal) (turn animal) (move animal) (eat animal) (reproduce animal)) *animals*) (add-plants))

(defun draw-world () (loop for y below *height* do (progn (fresh-line) (princ "|") (loop for x below *width* do (princ (cond ((some (lambda (animal) (and (= (animal-x animal) x) (= (animal-y animal) y))) *animals*) #\M) ((gethash (cons x y) *plants*) #\*) (t #\space)))) (princ "|")))) Evolution of Software Languages 12 10: LISP to Scheme LISP example5

(defun evolution () (draw-world) (fresh-line) (let ((str (read-line))) (cond ((equal str "quit") ()) (t (let ((x (parse-integer str :junk-allowed t))) (if x (loop for i below x do (update-world) if (zerop (mod i 1000)) do (princ #\.)) (update-world)) (evolution))))))

Evolution of Software Languages 13 10: LISP to Scheme Carl Hewitt

• Researcher at MIT • Built "Planner" • Defined "Actors" http://www.erlang-factory.com/sfbay2015/carl-hewitt • Hard to read papers • Fathered ACT-1, ... (Henry Lieberman) • (PhD with )

Evolution of Software Languages 14 10: LISP to Scheme The Actor Model1

Evolution of Software Languages 15 10: LISP to Scheme The Actor Model2 (define p (act->scheme '((define counter (BEHAVIOR (value) (METHOD (up n) (BECOME counter (+ value n))) (METHOD (down n) (BECOME counter (- value n))) (METHOD (display) (display "value=") (display value) (newline))))

(define c1 (NEW counter 0)) (define c2 (NEW counter 5))

(SEND c2 down 2) (SEND c1 up 1) (SEND c2 up 5) (SEND c1 display) (SEND c2 display)))) (define act-p (eval p (interaction-environment))) (act-p)) Evolution of Software Languages 16 10: LISP to Scheme The Actor Model2 (define p (act->scheme '((define counter (BEHAVIOR (value) (METHOD (up n) (BECOME counter (+ value n))) (METHOD (down n) (BECOME counter (- value n))) (METHOD (display) (display "value=") (display value) (newline))))

(define c1 (NEW counter 0)) (define c2 (NEW counter 5))

(SEND c2 down 2) (SEND c1 up 1) (SEND c2 up 5) (SEND c1 display) (SEND c2 display)))) (define act-p (eval p (interaction-environment))) (act-p)) Evolution of Software Languages 17 10: LISP to Scheme The Actor Model2 (define p (act->scheme '((define counter (BEHAVIOR (value) (METHOD (up n) (BECOME counter (+ value n))) (METHOD (down n) (BECOME counter (- value n))) (METHOD (display) (display "value=") (display value) (newline))))

(define c1 (NEW counter 0)) (define c2 (NEW counter 5))

(SEND c2 down 2) (SEND c1 up 1) (SEND c2 up 5) (SEND c1 display) (SEND c2 display)))) (define act-p (eval p (interaction-environment))) (act-p)) Evolution of Software Languages 18 10: LISP to Scheme The Actor Model2 (define p (act->scheme '((define counter (BEHAVIOR (value) (METHOD (up n) (list 'lambda empty (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list 'define 'counter (list (list 'lambda empty (list 'define 'methods (BECOME (list counter'$make-dictionary$)) (+ value (list n))) '$put$ 'methods (list 'quote 'up) (list 'lambda ((listMETHOD 'self (down 'become! n) 'value 'n) (list 'become! 'counter (list '+ 'value 'n)))) (list '$put$ 'methods (list 'quote 'down) (list 'lambda (list 'self 'become! 'value 'n) (list 'become! 'counter (list '- 'value ( 'n))))BECOME (list counter '$put$ 'methods (- value (list n)))'quote 'display) (list 'lambda (list 'self 'become! (METHOD 'value) (display)(list 'display "value=") (list 'display 'value) (list 'newline))) (list 'lambda (list 'args) (list 'define 'tail (list 'last 'args)) (list 'define (list 'dispatcher 'msg 'arg-list) (list 'set-cdr! (display 'tail 'arg-list) "value=") (list 'apply (list '$get$ 'methods 'msg) 'args)) 'dispatcher)))) (list 'define (display 'c1 (list '$make-actor$ value) 'counter 0)) (list 'define 'c2 (list '$make-actor$ 'counter 5)) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c2 (list 'quote (newline)))) 'down) 2) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c1 (list 'quote 'up) 1) (list '$exit$ (define '$scheduler$))) c1 (NEW (list counter '$new$ '$scheduler$ 0)) (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c2 (list 'quote 'up) 5) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list(define 'lambda c2 (list (NEW 'ignore) counter (list '$switch$5)) '$scheduler$) (list 'c1 (list 'quote 'display)) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c2 (list 'quote 'display)) (list '$exit$ '$scheduler$))) (list '$exit$ '$scheduler$))) (SEND c2 (list down '$start$ 2) '$scheduler$)) (SEND c1 up 1) (SEND c2 up 5) (SEND c1 display) (SEND c2 display)))) (define act-p (eval p (interaction-environment))) (act-p)) Evolution of Software Languages 19 10: LISP to Scheme The Actor Model2 (define p (act->scheme '((define counter (BEHAVIOR (value) (METHOD (up n) (list 'lambda empty (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list 'define 'counter (list (list 'lambda empty (list 'define 'methods (BECOME (list counter'$make-dictionary$)) (+ value (list n))) '$put$ 'methods (list 'quote 'up) (list 'lambda ((listMETHOD 'self (down 'become! n) 'value 'n) (list 'become! 'counter (list '+ 'value 'n)))) (list '$put$ 'methods (list 'quote 'down) (list 'lambda (list 'self 'become! 'value 'n) (list 'become! 'counter (list '- 'value ( 'n))))BECOME (list counter '$put$ 'methods (- value (list n)))'quote 'display) (list 'lambda (list 'self 'become! (METHOD 'value) (display)(list 'display "value=") (list 'display 'value) (list 'newline))) (list 'lambda (list 'args) (list 'define 'tail (list 'last 'args)) (list 'define (list 'dispatcher 'msg 'arg-list) (list 'set-cdr! (display 'tail 'arg-list) "value=") (list 'apply (list '$get$ 'methods 'msg) 'args)) 'dispatcher)))) (list 'define (display 'c1 (list '$make-actor$ value) 'counter 0)) (list 'define 'c2 (list '$make-actor$ 'counter 5)) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c2 (list 'quote (newline)))) 'down) 2) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$) (list 'c1 (list 'quote 'up) 1) (list '$exit$ (define '$scheduler$)))Welcome c1 ( NEW (listto counter '$new$DrScheme '$scheduler$ 0)) , (listversion 'lambda (list 372 'ignore) [3m]. (list '$switch$ '$scheduler$) (list 'c2 (list 'quote 'up) 5) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list(defineLanguage: 'lambda c2 (list (NEW 'ignore) Standardcounter (list '$switch$5)) (R5RS) '$scheduler$) custom (list 'c1 .(list 'quote 'display)) (list '$exit$ '$scheduler$))) (list '$new$ '$scheduler$ (list 'lambda (list 'ignore) (list '$switch$ '$scheduler$)started (list 'c2 (list 'quote 'display)) (list '$exit$ '$scheduler$))) (list '$exit$ '$scheduler$))) (SEND c2 (list down '$start$ 2) '$scheduler$)) (SENDvalue=1 c1 up 1) (SENDvalue=8 c2 up 5) (SENDno c1more display) processes (SEND c2 display)))) (define act-p (eval p (interaction-environment))) (act-p)) Evolution of Software Languages 20 10: LISP to Scheme The Actor Model3

::= * ::= | | | | |

::= (BEHAVIOR (*) *) ::= (BECOME *) ::= (NEW *) ::= (SEND *) ::= SELF ::= scheme-expression

::= (METHOD ( *) *)

::= identifier ::= identifier ::= identifier

Evolution of Software Languages 21 10: LISP to Scheme The Actor Model4

(define Factorial (BEHAVIOR () (METHOD (doit customer number) (BECOME Factorial) (display number) (newline) (if (= number 0) (SEND customer result 1) (let ((x (NEW FactCust customer number))) (SEND SELF doit x (- number 1)))))))

Evolution of Software Languages 22 10: LISP to Scheme The Actor Model4

(define FactCust (BEHAVIOR (customer number1) (METHOD (result number2) (SEND customer result (* number1 number2)))))

(define Factorial (BEHAVIOR () (METHOD (doit customer number) (BECOME Factorial) (display number) (newline) (if (= number 0) (SEND customer result 1) (let ((x (NEW FactCust customer number))) (SEND SELF doit x (- number 1)))))))

Evolution of Software Languages 23 10: LISP to Scheme The Actor Model4

(define FactCust (BEHAVIOR (customer number1) (METHOD (result number2) (SEND customer result (* number1 number2)))))

(define Factorial (BEHAVIOR () (METHOD (doit customer number) (BECOME Factorial) (define User (display number) (newline) (BEHAVIOR (fact) (if (= number 0) (METHOD (doit number) (SEND customer result 1) (SEND fact doit SELF number)) (let ((x (NEW FactCust customer number))) (METHOD (result number) (SEND SELF doit x (- number 1))))))) (display (list "Value= " number)) (newline))))

Evolution of Software Languages 24 10: LISP to Scheme The Actor Model4

(define FactCust (BEHAVIOR (customer number1) (METHOD (result number2) (SEND customer result (* number1 number2)))))

(define Factorial (BEHAVIOR () (METHOD (doit customer number) (BECOME Factorial) (define User (display number) (newline) (BEHAVIOR (fact) (if (= number 0) (METHOD (doit number) (SEND customer result 1) (SEND fact doit SELF number)) (let ((x (NEW FactCust customer number))) (METHOD (result number) (SEND SELF doit x (- number 1))))))) (display (list "Value= " number)) (newline))))

(define fact (NEW Factorial)) (SEND (NEW User fact) doit 10) (SEND (NEW User fact) doit 4)

Evolution of Software Languages 25 10: LISP to Scheme The Actor Model5 (define Fibonacci (BEHAVIOR (first second) (METHOD (fib customer number) (BECOME Fibonacci first second) (cond ((= number 0) (SEND customer result first)) ((= number 1) (SEND customer result second)) (else (let ((x (NEW FibCust customer))) (SEND SELF fib x (- number 1)) (SEND SELF fib x (- number 2))))))))

(define FibCust (BEHAVIOR (customer) (METHOD (result number) (BECOME FibCust2 customer number)))) (define Print (define FibCust2 (BEHAVIOR () (BEHAVIOR (customer number1) (METHOD (result number) (METHOD (result number2) (BECOME Print) (SEND customer result (+ number1 number2)) (display (BECOME FibCust2 customer number1)))) "result=") (display number) (define User (newline)))) (BEHAVIOR (fibonacci) (METHOD (doit number) (define fib (NEW Fibonacci 1 1)) (BECOME User fibonacci) (SEND (NEW User fib) doit 6) (SEND fibonacci fib (NEW Print) number)))) (SEND (NEW User fib) doit 4) Evolution of Software Languages 26 10: LISP to Scheme The Actor Model6

• Very high-level view on concurrency • Most famous offshoot: Erlang • Basis for process calculi • Imperative (see BECOME) • Asynchronous • No (evident) global state • Inherently concurrent • (Unbounded) non deterministic

Evolution of Software Languages 27 10: LISP to Scheme Guy Steele - Gerald Sussman

• Researchers at MIT • Built "Scheme" ←Common Lisp →SICP →PhD with Seymour Papert https://en.wikipedia.org/wiki/Guy_L._Steele,_Jr. ←PhD with →

http://cunydhi.commons.gc.cuny.edu/2015/03/21/ should-we-fear-intelligent-machines/

Evolution of Software Languages 28 10: LISP to Scheme The case of Scheme

from AIM-848

Evolution of Software Languages 29 10: LISP to Scheme Sussman and Steele December 22 1875 48 leeentatlon of the in ter reter

Scheme and Actors Acknowledgements

This paper would not have happened if Sussman had not been forced to think about lambda calculus by having to teach 6,031, nor would it have happened had not Steele been forced to understand PLASNA by morbid curiosity. This work developed out of an initial attempt to understand the . actorness of actors. Steele thought he understood it, but couldn't explain it; Sussman suggested the experimental approach of actually building an "ACTORS ". This interpreter attempted to intermix the use of actors and LISP lambda expressions in a clean manner. When it was completed, we discovered that the "actors" and the lambda expressions were identical in implementation. Once we had discovered this, all the rest fell into place, and it was only natural to begin thinking about actors in terms of lambda calculus. The original interpreter was call-by-name for various reasons having to do with 6.031; we subsequently experimentally discovered how call- by-name screws iteration, and rewrote it to use call-by-value. Note well that, we did not bring forth a clean implementation in one brilliant flash of understanding; we used an experimental and highly empirical approach to bootstrap our knowledge. We wish to thank the staff of 6.031, Nike Dertouzos, and Steve Ward, for precipitating this intellectual adventure. Carl Hewitt spent many hours explaining the innards and outards of PLASI'IA to Steele over the course of several months; Narilyn McClennan was also helpf'ul in this respect. Brian Smith and Richard Zippel helped a lot. We wish to thank Seymourfrom Papert, AIM- 349Ben Kuipers, Narvin Ninsky, and Vaughn Pratt for their excellent suggestions.

Evolution of Software Languages 30 10: LISP to Scheme A timeline for Scheme1 43pp

35pp 76pp

Evolution of Software Languages 31 10: LISP to Scheme A timeline for Scheme2 43pp

55pp 1986

50pp 1991

1998

88pp

2007 90pp

+ IEEE Standard 1178-1990 DRAFT

Evolution of Software Languages 32 10: LISP to Scheme Semantics for Scheme1 AIM-349 ⤑ informal lambda-calculus substitution semantics

AIM-452 ⤑ informal

... a formal definition of the semantics of Scheme AIM-848 (RRRS) ⤑ will be included in a separate report ...

R3RS ⤑ denotational semantics + rewrite rules

denotational semantics + rewrite rules + macros R4RS ⤑ (added support for immutables)

R5RS ⤑ denotational semantics + syntactic forms

R6RS ⤑ operational semantics

denotational semantics + syntactic forms R7RS ⤑ (added support for dynamic-wind) Evolution of Software Languages 33 10: LISP to Scheme Semantics for Scheme2 Page 33 from R3RS 33 from Page

Evolution of Software Languages 34 10: LISP to Scheme I . may be lexically bound by lambda-expressions. There is a global environment contai.ning values for (some} free variables. Nany of the variables in this global environment initially have as their values primitive operations such as, for example, cAR, coMs, and pLUs. SCHENE dif'fers from most LISP systems in t hat the atom cat iS not itself an operation (in the sense of b e i n g a n invocable object, e.g. a valid first argument to AvvLY), but only has one as a value when considered as an identifier. Non-atomic forms are divided by the evaluator into two classes: combinations and "magic (special) forms". T he BNF given above is ambiguous; any magic form an also be p a r s e d as a combination. The e valuator always treats an ambiguous case 'as a magic form. Nagic forms are recognized by the presence of a "magic (reserved) word" in the car position of the form. All non-atomic forms which are not magic forms are considered to be combinations. The system has a small initial set of magic words; there is also a mechanism for creating new ones (Note FUMCALL is a Pain). A combination is considered to be a list of subforms. These subforms are all evaluated. The first value must be a procedure; it is applied to the other values to get the value of the combination. There are four important p oints he r e :

(I) T he procedure position is always evaluated just l ike an y o t he r position. (This is why the primitive operators are. the values o f globa l identifiers.)

( <) The procedure is never "r e-evaluated"; if the first subfoi m fails to e valuate to an applicable procedure, it is an error . Thu s , u n l i k e most LISP systems, SCHENE always evaluates the first subform of a combination e xactly on c e . e.g.(3) The arguments argumentare all completely evaluated before theevaluation procedure is applied; that is, SCHENE, like most LISP systems, is an applicative-order language. Nany SCHENE programs exploit this fact.

(4) The argument forms (and procedure f'orm) may in principle be evaluated i n any order. This is unlike the usual LISP left-to-right order . (All SCHEI'lE interpreters implemented so far have in fact performed left-to-right AIM-452 evaluation, but we do not wish programs to depend on this fact. Indeed, the~e are some reasons why a clever interpreter might want to evaluate them right-to-left,The Revised Revisede.g. toReport get thingson Scheme on a stack in the correct order.}

(operator operandf ...) essential special form A list whose first element is not the keyword of a special form indicates a procedure eall. The operator and operand expressions areevaluated and the resulting procedure is passed the resulting arguments. In contrast to other AIM-848 dialects of Lisp the order of evaluation is not specified, and the operator expression and the operand expressions are always evaluated with the same evaluation rules. (+ 3 4) ( (11.' 0!false + +) 3 4) ℇ ⟦(E0 E*)⟧ = R3RS(quote → R7RSdatum) \ R6RS essential special form λρκ . ℇ*(permute (⟨E0⟩ § E*)) datum essential special form The order of evaluation within a call is unspecified. We mimic ρ Evaluates to datum. This notation is used to include literal constants in that here by applying arbitrary permutations permute and (λε* . ((λε* . applicate (ε* ↓ 1) (ε* † 1) κ) Scheme code. unpermute, which must be inverses, to the arguments in a call (unpermute ε*))) before and after they are evaluated. This(quote {still a)requires | is not a. quite right since it suggests, incorrectly, } that the order of ( quote 0(a b c) ) 4(a b c) evaluation is constant throughout a program (for any given number of arguments), but it is a closer( quote approximation (+ 1 2) to ) the (+ 1 2) intended semantics than a left-to-right evaluation would be. (quote datum) may be abbreviated as 'datum. The two notations are equiv- alent in all respects. Evolution of Software Languages 35 10: LISP to Scheme 'a '4(a b c) C(a b c) '(+ 1 2) (+ 1 2) '(quote a) (quote a) (quote a) Numeric constants, string constants, character constants, vect;or constants, a nd the constants 0! true, 0! f a l s e , an d 0 ! nul l n e e d no t b e quoted.

> IIgb(. II II gb( II II abC II gb(. II '146932 145932 146932 146932 '0!true 0!true t!true 0!true

(lambda (earl ...) ezpr) essential special form Each ear must be an identifier. The lambda expression evaluates to a pro- cedure with formal argument list (uar1 ... ) and procedure body ezpr The. environment in effect when the lambda expression was evaluated is rernem- bered as part of the procedure. When the procedure is later called with some Glitches1

Welcome to DrScheme, version 372 [3m]. Language: Standard (R5RS) custom. > (define (f) '(1 . 2)) > (define z (f)) > (set-car! z 3) > z (cons 3 2) > (f) (cons 3 2) >

Evolution of Software Languages 36 10: LISP to Scheme Glitches2

Welcome to DrScheme, version 372 [3m]. Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) 1

Evolution of Software Languages 10: LISP to Scheme 37 Glitches2

Welcome to DrScheme, version 372 [3m]. Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) Welcome to DrScheme, version 6.0 [3m]. 1 Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) #

Evolution of Software Languages 10: LISP to Scheme 38 Glitches2

Welcome to DrScheme, version 372 [3m]. Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) Welcome to DrScheme, version 6.0 [3m]. 1 Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) Welcome to DrScheme, version 6.0 [3m]. # Language: Standard (R5RS) custom. > (define (f) (define x 1) (define y x) y) > (f) 1

Evolution of Software Languages 10: LISP to Scheme 39 Showcase: metacircularity1 (define circularity-level 0) ; only 1st time

(begin (define old-circularity-level circularity-level) (define circularity-level (+ old-circularity-level 1)) (define meta-level-eval eval) (define eval '()) (define environment '())

(define (loop output) (define rollback environment)

(define (evaluate expression) ... )

(display output) (newline) (display "level") (display circularity-level) (display ">") (set! eval evaluate) (loop (evaluate (read))))

(loop "Lisp in 100 lines")) Evolution of Software Languages 10: LISP to Scheme 40 Showcase: metacircularity2

Welcome to DrScheme, version 372 [3m]. Language: Standard (R5RS) custom. Lisp in 100 lines level:1>(begin (define old-circularity-level circularity-level) (define circularity-level (+ old-circularity-level 1)) (define meta-level-eval eval) (define eval '()) (define environment '())

(define (loop output)

... this is where I feed the interpreter 3x to itself Lisp in 100 lines level:4>(+ 1 2) 3

Evolution of Software Languages 10: LISP to Scheme 41 Showcase: metacircularity3 (define (evaluate expression)

(define (error message qualifier) (display message) (set! environment rollback) (loop qualifier))

; functions

(define (bind-variable variable value) ... (define (bind-parameters parameters arguments) ... (define (evaluate-sequence expressions) ... (define (make-procedure parameters expressions) ...

; evaluation functions

...

(if (symbol? expression) (evaluate-variable expression) (if (pair? expression) ...

expression))) Evolution of Software Languages 10: LISP to Scheme 42 Showcase: metacircularity3 (define (evaluate expression)

(define (error message qualifier) (display message) (set! environment rollback) (if (symbol? expression) (loop qualifier)) (evaluate-variable expression) (if ( pair? ;expression) functions (apply (if ( equal? (define (car (bind-variable expression) 'begin variable) evaluate-begin value) ... ( if ( equal?(define ( car(bind-parameters expression) 'define parameters) evaluate-define arguments) ... ( if ((defineequal? (evaluate-sequence(car expression) 'if expressions)) evaluate-if ... ( if(define (equal? (make-procedure (car expression) parameters 'lambda )expressions) evaluate-lambda ... (if (equal? (car expression) 'quote) evaluate-quote ; evaluation(if (equal? functions (car expression) 'set!) evaluate-set! (evaluate-application (car expression)))))))) (cdr expression)) ... expression))) (if (symbol? expression) (evaluate-variable expression) (if (pair? expression) ...

expression))) Evolution of Software Languages 10: LISP to Scheme 43 Showcase: metacircularity3 (define (evaluate expression)

(define (error message qualifier) (display message) (set! environment rollback) (loop qualifier)) (define (make-procedure parameters expressions)

(define lexical-environment environment) ; functions (define procedure '())

(lambda arguments (define (bind-variable variable value) ... (define dynamic-environment environment) (define (bind-parameters parameters arguments) ... (set! environment lexical-environment) (define (evaluate-sequence expressions) ... (bind-parameters parameters arguments) (define (make-procedure parameters expressions) ... (begin

(set! procedure (evaluate-sequence expressions)) ; evaluation functions (set! environment dynamic-environment)

procedure))) ...

(if (symbol? expression) (evaluate-variable expression) (if (pair? expression) ...

expression))) Evolution of Software Languages 10: LISP to Scheme 44 Conclusion • Arguably the most expressive • Also the first grounded programming language • Source of inspiration for many other languages • The start of • The start of language semantics • The start of and reflection • The starting platform for AI • Continues with Common Lisp as a commercially viable platform • And also so many things more ...

Evolution of Software Languages 45 10: LISP to Scheme Assignment

1. Construct an unbounded queue in the actor model 2. Make Lisp-in-100-lines run in Racket 3. Translate it into (a) Lisp

Evolution of Software Languages 46 10: LISP to Scheme