Download presentation
Presentation is loading. Please wait.
1
Operational Semantics of Scheme
September 4, 1997 Operational Semantics of Scheme CS 550 Programming Languages Jeremy Johnson
2
September 4, 1997 Theme This lecture explores of the operational semantics of scheme programs. Previously we informally discussed the substitution model of computation. We review the substitution model and show that it fails when assignment is allowed. A model of computation based on environments is introduced to overcome this shortcoming. An interpreter is implemented that demonstrate this model. The interpreter operationally defines scheme. Several variants are investigated
3
Operational Semantics
The behavior of a program is specified in terms of the operation of an abstract machine. The abstract machine uses terms of the language as its “machine code.” The machine has a state, which for simple languages is just a term in the language, and a transition function that specifies how to move from one state to the next. The meaning of the program is the final state of the abstract machine.
4
Outline Substitution model of computation
September 4, 1997 Outline Substitution model of computation Modeling state with assignment Environments Scheme interpreter (meta-circular) Efficient implementation
5
Starting Point Informal Scheme Semantics
September 4, 1997 Starting Point Informal Scheme Semantics To evaluate (E1 E2 ... En), recursively evaluate E1, E2,...,En - E1 should evaluate to a function - and then apply the function value of E1 to the arguments given by the values of E2,...,En. In the base case, there are self evaluating expressions (e.g. numbers and symbols). In addition, various special forms such as quote and if must be handled separately.
6
Substitution Model of Computation
September 4, 1997 Substitution Model of Computation function application corresponds to substituting the argument expressions into the formal parameters of the function body Order of evaluation Applicative vs. normal order lambda calculus Church-Rosser
7
Substitution Example (define (square x) (* x x))
September 4, 1997 Substitution Example (define (square x) (* x x)) (define (sum-of-squares x y) (+ (square x) (square y))) (define (f a) (sum-of-squares (+ a 1) (* a 2))) [applicative order] (f 5) (sum-of-squares (+ 5 1) (* 5 2)) (+ (square 6) (square 10)) (+ (* 6 6) (* 10 10)) ( ) 136 [normal order] (+ (square (+ 5 1)) (square (* 5 2)) ) (+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2))) (+ (* 6 6) (* 10 10)) ( )
8
Order Matters (define (p) (p)) (define (test x y) (if (= x 0) y))
September 4, 1997 Order Matters (define (p) (p)) (define (test x y) (if (= x 0) y)) (test 0 (p))
9
September 4, 1997 Environments When assignment is introduced the substitution model falls apart and a different, more complicated model, must be used. Environments used to store variables and bindings. Env = list of frames Frame = list of bindings Values can change assignment supported List of frames to support nested scope
10
Modeling State with Assignment
September 4, 1997 Modeling State with Assignment (define (make-withdraw balance) (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds"))) Make-withdraw can be used as follows to create two objects W1 and W2: (define W1 (make-withdraw 100)) (define W2 (make-withdraw 100)) (W1 50) 50 (W2 70) 30 (W2 40) "Insufficient funds" (W1 40) 10
11
Modeling State with Assignment
September 4, 1997 Modeling State with Assignment (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) (define (dispatch m) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) (define acc (make-account 100)) ((acc 'withdraw) 50) 50 ((acc 'withdraw) 60) "Insufficient funds" ((acc 'deposit) 40) 90 ((acc 'withdraw) 60) 30
12
Cost of Assignment (define (make-simplified-withdraw balance)
September 4, 1997 Cost of Assignment (define (make-simplified-withdraw balance) (lambda (amount) (set! balance (- balance amount)) balance)) (define W (make-simplified-withdraw 25)) (W 10) 15 5 (define (make-decrementer balance) (- balance amount))) (define D (make-decrementer 25)) (D 10)
13
Substitution Model Fails
September 4, 1997 Substitution Model Fails (make-decrementer 25) 20) ((lambda (amount) (- 25 amount)) 20) ( ) 5 ((make-simplified-withdraw 25) 20) ((lambda (amount) (set! balance (- 25 amount)) 25) 20) (set! balance ( )) 25
14
Environment Model Solves Problem
September 4, 1997 Environment Model Solves Problem (define W1 (make-withdraw 100)) (W1 50) (define W2 (make-withdraw 100)) Make-withdraw Global Env W1 W2 Balance = 50 Balance = 100 E1 E2 Parameters body
15
September 4, 1997 Scheme Interpreter To evaluate a combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions. To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.
16
Eval and Apply
17
Scheme Interpreter: eval
September 4, 1997 Scheme Interpreter: eval (define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp))))
18
Scheme Interpreter: apply
September 4, 1997 Scheme Interpreter: apply (define (apply procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type -- APPLY" procedure))))
19
Dynamic vs. Static Scope
September 4, 1997 Dynamic vs. Static Scope Static scope (define (make-adder x) (lambda (y) (+ x y))) (define add1 (make-adder 1)) (define x 2) (add1 2) 3 Dynamic scope 4
20
Scheme Interpreter: dynamic eval
September 4, 1997 Scheme Interpreter: dynamic eval (define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ; don't need to store env - not used. JRJ ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env) env)) ; added env as an argument to apply. JRJ (else (error "Unknown expression type -- EVAL" exp))))
21
Scheme Interpreter: dynamic apply
September 4, 1997 Scheme Interpreter: dynamic apply (define (apply procedure arguments env) ; added env parameter. JRJ (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments env ))) ; extend runtime env instead of procedure-environment (else (error "Unknown procedure type -- APPLY" procedure))))
22
September 4, 1997 Practice Exercise Trace scheme interpreter from SICP using as input the following two expressions [you will have to add =, *, - as primitive procedures for this to work]. (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (fact 3)
23
September 4, 1997 Practice Exercises Modify the SICP interpreter to use dynamic instead of static scope. Provide an example where the same code provides two different answers depending on which scoping rule is used. Add the let expression to the interpreter How can you convert (let ((n1 v1) … (nt vt)) E) to an equivalent scheme expression already handled by the scheme interpreter
24
September 4, 1997 Abstract Machine Operational meaning of a program is a description of an abstract machine (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) 1 fact n n! = * - fact 1
25
Universal Machine Input: description of machine
September 4, 1997 Universal Machine Input: description of machine Emulate machine described eval n n! (define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))))
26
September 4, 1997 Efficiency of eval The scheme interpreter is inefficient because it interleaves syntactic analysis with evaluation What happens when (fact 3) is evaluated? eval can be made more efficient if syntactic analysis is performed only once Split eval into analysis and execution analyze takes expr and produces a function of env that encapsulates the work to be done by expr
27
Separating Syntactic Analysis from Execution
September 4, 1997 Separating Syntactic Analysis from Execution (define (eval exp env) ((analyze exp) env)) (define (analyze exp) (cond ((self-evaluating? exp) (analyze-self-evaluating exp)) ((quoted? exp) (analyze-quoted exp)) ((variable? exp) (analyze-variable exp)) ((assignment? exp) (analyze-assignment exp)) ((definition? exp) (analyze-definition exp)) ((if? exp) (analyze-if exp)) ((lambda? exp) (analyze-lambda exp)) ((begin? exp) (analyze-sequence (begin-actions exp))) ((cond? exp) (analyze (cond->if exp))) ((application? exp) (analyze-application exp)) (else (error "Unknown expression type -- ANALYZE" exp))))
28
analyze (define (analyze-self-evaluating exp) (lambda (env) exp))
September 4, 1997 analyze (define (analyze-self-evaluating exp) (lambda (env) exp)) (define (analyze-variable exp) (lambda (env) (lookup-variable-value exp env))) (define (analyze-assignment exp) (let ((var (assignment-variable exp)) (vproc (analyze (assignment-value exp)))) (lambda (env) (set-variable-value! var (vproc env) env) 'ok)))
29
analyze (define (analyze-if exp)
September 4, 1997 analyze (define (analyze-if exp) (let ((pproc (analyze (if-predicate exp))) (cproc (analyze (if-consequent exp))) (aproc (analyze (if-alternative exp)))) (lambda (env) (if (true? (pproc env)) (cproc env) (aproc env))))) (define (analyze-lambda exp) (let ((vars (lambda-parameters exp)) (bproc (analyze-sequence (lambda-body exp)))) (lambda (env) (make-procedure vars bproc env)))) ; analyze-sequence composes the functions in the sequence
30
analyze (define (analyze-application exp)
September 4, 1997 analyze (define (analyze-application exp) (let ((fproc (analyze (operator exp))) (aprocs (map analyze (operands exp)))) (lambda (env) (execute-application (fproc env) (map (lambda (aproc) (aproc env)) aprocs))))) (define (execute-application proc args) (cond ((primitive-procedure? proc) (apply-primitive-procedure proc args)) ((compound-procedure? proc) ((procedure-body proc) (extend-environment (procedure-parameters proc) args (procedure-environment proc)))) (else (error "Unknown procedure type -- EXECUTE-APPLICATION" proc))))
31
September 4, 1997 Practice Exercise Trace scheme interpreter that separates analysis from execution using as input the following two expressions. Compare to the first interpreter. Which is more efficient and why? (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (fact 3) First call analyze directly on this sequence of expressions [you can wrap them in a begin] and then apply the resulting function to the-global-environment
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.