abstract machines for great good
TRANSCRIPT
_epicmonkey [email protected]
Grimm Brothers
• (Grand) Mother tells a story to her (grand) children
• Very beginnings of culture
• Find and collect stories that passed through the sieve of history
Germany before unification
• A collection of different
• People mostly spoke German, English, France
• Collect stories to bind the German speaking peoples together
JFK Moon Speech
We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.
• 1920s: Birth of Combinatory Logic
• Schonfinkel to eliminate bound variables
• Briefly covered high order functions
• Von Neumann's doctoral thesis on set theory
• Curry's combinators
History of Lambda Calculus
• 1930s: Birth of Lambda calculus
• Alonzo Church invented Lambda calculus (explicit formal convertion rules)
• Representation of positive integers — Church numerals
• Turing published first fixed-point combinator
History of Lambda Calculus
History of Lambda Calculus• 1940s and 1950s:
• Research sort of is frozen, though - - -
• Simple type theory
• Weak reduction
History of Lambda Calculus• 1960+:
• John McCarthy Computer language LISP
• Peter Landin — abstract machine
• Bohm's CuCh language
• Types
λx.λy.x λx.λy.y
λf.λx.x λf.λx.f x λf.λx.f (f x)
λm.λn.λf.λx.((m f) ((n f) x)) λp.λq.((p (λx.λy.x)) q)
Basic LambdaTrue False
Zero One Two
Add Or
((λ (l) (((λ (f) ((λ (g) (f (λ (x) ((g g) x)))) (λ (g) (f (λ (x) ((g g) x)))))) (λ (r) (λ (l) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) ((λ (p) (p (λ (x) (λ (y) (λ (x) (λ (y) y)))))) l)) (λ (x) (λ (x) (λ (y) x)))) ((λ (p) ((λ (s) (((λ (x) (λ (y) ((((λ (f) ((λ (g) (f (λ (x) ((g g) x)))) (λ (g) (f (λ (x) ((g g) x)))))) (λ (r) (λ (x) (λ (y) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) ((λ (p) (p (λ (x) (λ (y) (λ (x) (λ (y) y)))))) x)) y) (((λ (p) (λ (q) (λ (h) ((h p) q)))) ((λ (p) (p (λ (x) (λ (y) x)))) x)) ((r ((λ (p) (p (λ (x) (λ (y) y)))) x)) y))))))) x) y))) (((λ (x) (λ (y) ((((λ (f) ((λ (g) (f (λ (x) ((g g) x)))) (λ (g) (f (λ (x) ((g g) x)))))) (λ (r) (λ (x) (λ (y) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) ((λ (p) (p (λ (x) (λ (y) (λ (x) (λ (y) y)))))) x)) y) (((λ (p) (λ (q) (λ (h) ((h p) q)))) ((λ (p) (p (λ (x) (λ (y) x)))) x)) ((r ((λ (p) (p (λ (x) (λ (y) y)))) x)) y))))))) x) y))) (r (((λ (p) (λ (l) ((((λ (f) ((λ (g) (f (λ (x) ((g g) x)))) (λ (g) (f (λ (x) ((g g) x)))))) (λ (r) (λ (p) (λ (l) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) ((λ (p) (p (λ (x) (λ (y) (λ (x) (λ (y) y)))))) l)) (λ (x) (λ (x) (λ (y) x)))) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) (p ((λ (p) (p (λ (x) (λ (y) x)))) l))) (((λ (p) (λ (q) (λ (h) ((h p) q)))) ((λ (p) (p (λ (x) (λ (y) x)))) l)) ((r p) ((λ (p) (p (λ (x) (λ (y) y)))) l)))) ((r p) ((λ (p) (p (λ (x) (λ (y) y)))) l)))))))) p) l))) (λ (x) (((λ (x) (λ (y) ((λ (n) ((n (λ (x) (λ (x) (λ (y) y)))) (λ (x) (λ (y) x)))) (((λ (m) (λ (n) ((n (λ (n) (λ (f) (λ (x) (((n (λ (g) (λ (h) (h (g f))))) (λ (u) x)) (λ (u) u)))))) m))) x) y)))) x) p))) s))) (((λ (p) (λ (q) (λ (h) ((h p) q)))) p) (λ (x) (λ (x) (λ (y) x)))))) (r (((λ (p) (λ (l) ((((λ (f) ((λ (g) (f (λ (x) ((g g) x)))) (λ (g) (f (λ (x) ((g g) x)))))) (λ (r) (λ (p) (λ (l) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) ((λ (p) (p (λ (x) (λ (y) (λ (x) (λ (y) y)))))) l)) (λ (x) (λ (x) (λ (y) x)))) ((((λ (p) (λ (x) (λ (y) ((p x) y)))) (p ((λ (p) (p (λ (x) (λ (y) x)))) l))) (((λ (p) (λ (q) (λ (h) ((h p) q)))) ((λ (p) (p (λ (x) (λ (y) x)))) l)) ((r p) ((λ (p) (p (λ (x) (λ (y) y)))) l)))) ((r p) ((λ (p) (p (λ (x) (λ (y) y)))) l)))))))) p) l))) (λ (x) (((λ (x) (λ (y) ((λ (p) ((p (λ (x) (λ (y) y))) (λ (x) (λ (y) x)))) (((λ (x) (λ (y) ((λ (n) ((n (λ (x) (λ (x) (λ (y) y)))) (λ (x) (λ (y) x)))) (((λ (m) (λ (n) ((n (λ (n) (λ (f) (λ (x) (((n (λ (g) (λ (h) (h (g f))))) (λ (u) x)) (λ (u) u)))))) m))) x) y)))) x) y)))) x) p))) s)))) ((λ (p) (p (λ (x) (λ (y) y)))) l))) ((λ (p) (p (λ (x) (λ (y) x)))) l)))))) l)) (((λ (p) (λ (q) (λ (h) ((h p) q)))) (λ (f) (λ (x) (f (f (f x)))))) (((λ (p) (λ (q) (λ (h) ((h p) q)))) (λ (f) (λ (x) (f x)))) (((λ (p) (λ (q) (λ (h) ((h p) q)))) (λ (f) (λ (x) (f (f x))))) (λ (x) (λ (x) (λ (y) x)))))))
Not so Basic Lambda / Quicksort
Abstract Machine
• How does one design an abstract machine?
• Why do some abstract machines operate on λ-terms directly whereas others operate on compiled λ-terms?
• How does one prove the correctness of an abstract machine?
Abstract Machine• Does not need tree-shaped data structure to interpreter
code — much better performance
• Does not compile code to a native machine instructions — freedom and architecture-independent
• AM compiles code to a sequence of (abstract) instructions, defines reduction strategy, evaluation order and data representations
• Call-by-name (lazy) and call-by-value (eager) defined by an evaluation strategy that results into different machines
Abstract Machine
• Landin invented SECD machine
• Plotkin proved its correctness
• Felleisen invented CEK machine
• Many others proposed modifications and other discoverables
Abstract Machine for Arithmetic Expressions
• Arithmetic expression:
• a ::= N | a1 + a2 | a1 − a2 | . . .
• Instruction set:
• C(N) — push integer N on stack
• ADD — pop two integers, push their sum
• SUB — pop two integers, push their difference
Evaluation scheme
• E(N) = C(N)
• E(a1 + a2) = E(a1); E(a2); ADD
• E(a1 - a2) = E(a1); E(a2); SUB
• Example: E(3+(2-1)) = C(3); C(2); C(1); SUB; ADD
SECD Machine
S — Stack (holding intermediate results and return addresses)
E — Environment (giving values to symbols)
C — Code (instructions yet to be executed)
D — Dump (S.E.C)
SECD Machine• Instruction set (forget for a moment about Wikipedia):
• ACCESS(n) — push n-th field of the environment
• CLOSURE(c) — push closure of code c with current environment
• APPLY — pop function closure and argument, perform application
• RETURN — terminate current function, jump back to caller
• LET* — pop value and add it to environment
• ENDLET* — discard first entry of environment
De Bruijn Indices
λx.λy.x λx.λy.y
λf.λx.x λf.λx.f x λf.λx.f (f x)
True False
Zero One Two
λx1.λx0.x0 λx1.λx0.x1
λx1.λx0.x0 λx1.λx0.x1 x0 λx1.λx0.x1 (x1 x0)
Evaluation scheme
• E(n) = ACCESS(n)
• E(λa) = CLOSURE(E(a); RETURN)
• E(let a in b) = E(a); LET; E(b); ENDLET
• E(a b) = E(a); E(b); APPLY
Tail call optimization• tail call optimization drops extra RETURN
instruction enabling function to return result directly to function and saving stack space
• E(λa) = CLOSURE(E(a); RETURN)
Evaluation scheme• T(let a in b) = E(a); LET; T(b)
• T(a b) = E(a); E(b); TAILAPPLY
• T(a) = E(a); RETURN
• E(n) = ACCESS(n)
• E(λa) = CLOSURE(T(a))
• E(let a in b) = E(a); LET; E(b); ENDLET
• E(a b) = E(a); E(b); APPLY
K Machine
S — Stack (holding intermediate results and return addresses)
E — Environment (giving thunks to symbols)
C — Code (instructions yet to be executed)
Evaluation scheme• E(n) = ACCESS(n) • E(λa) = GRAB; E(a) • E(a b) = PUSH(E(b)); E(a)
• ACCESS — start evaluating the N-th thunk in the environment • PUSH(c) — push a thunk for code c • GRAB — pop one argument and add it to environment
Example: (λx. x+1) 2 = PUSH(C(2)); GRAB; ACCESS(1); C(1); ADD
Wanna know more?
• ZAM-, B-, G- machines
• BLC
• Cata-, Hylo-, Ana- morphisms as a reduction
• P-numerals vs Church version
• Ultimately, Read T.S.Eliot