280 likes | 577 Views
Procedures. EOPL3: Section 3.3 PROC and App B: SLLGEN. The PROC language. Expression ::= proc (Identifier) Expression AST: proc-exp ( var body) Expression ::= (Expression Expression ) AST: call-exp ( rator rand) PROC includes all of LET language Anonymous procedure
E N D
Procedures EOPL3: Section 3.3 PROC and App B: SLLGEN
The PROC language • Expression ::= proc (Identifier) Expression • AST: proc-exp (var body) • Expression ::= (Expression Expression) • AST: call-exp (rator rand) • PROC includes all of LET language • Anonymous procedure • One parameter always
Semantics of Procedures • (This slide is for procedures in general.) • Procedure Definition • Store formal parameters and body • Procedure Invocation • Evaluate body in an environment that binds formals to actual argument values • Interpretation of free-variables: Two methods • Use env at proc definition (lexical/static scoping) • Use env at proc call (dynamic scoping)
Scoping and Binding • references • (f x y) • f, x, and y • declarations • (lambda (x) (+ x 3)) • (let ((x (+ y 7))) (+ x 3)) • y, and second/right x are refs • first/left x is a declaration • lexical scoping rules
Kinds of Scope • Static or Lexical scope • determined by structure of program • Scheme, C++, Java, and many compiled languages • Dynamic scope • determined by path of execution • Lisp dialects, Perl, and many interpreted languages • Global Scope • File scope • Local Scope • Block • Body of a procedure • Body of a loop • Scope alters the meaning
Example-1 of PROC • let f = proc (x) --(x,11) in (f (f 77)) • Defines an anonymous procedure with one formal parameter named x. • Body of the procedure: --(x,11) • Binds the name f to this procedure. • Invokes f with actual argument 77. • Invokes f again with the result of above. • (will use two -- just for visibility)
Example-2 of PROC • (proc (f) (f (f 77))proc (x) --(x,11)) • This example is derived from the production • Expression ::= (ExpressionExpression) • so is (f(f 77)) • so is (f77) • proc (f) (f (f 77)) is the rator. • It defines an anonymous procedure with one formal parameter named f. • proc (x) --(x,11)) is the rand. • It also defines an anonymous procedure with one formal parameter named x.
Example-3 of PROC • let x = 200in let f = proc (z) --(z, x)in let x = 100 in let g = proc (z) --(z, x) in --((f 1), (g 1)) • Illustrates scope issues • x and z appear four times each. • Lexical scoping • In --((f 1), (g 1)), the bodies of f and g must be evaluated in the env they were defined. • In f, x is bound to 200 • In g, x is bound to 100
Example Programs of PROC • Example-1 and -2 produce same result, but different mechanisms. • Previous two slides gave semantics informally • Watch out: a very seductive approach • Next few slides: interpreter based
Recall value-of • value-of is an operator with two operands • an AST • an environment • (value-of astenv) • PROC = LET + two more productions • Bring in all value-of specs from LET • Additions are shown on next few slides …
additional value-of specs • (value-of (proc-exp var body) ρ) = (proc-val (procedure var body ρ)) • (value-of (call-exp rator rand) ρ) = (let ( (proc (expval->proc (value-of ratorρ))) (arg (value-of rand ρ))) (apply-procedure proc arg)) • To be defined: proc-val, apply-procedure
Spec of apply-procedure • (apply-procedure (procedure var body ρ)val) = (value-of body [var=val]ρ ) • apply-procedure takes two arguments: • an AST of a procedure definition • an argument for the parameter of the procedure • yields an expressed value
Impl of apply-procedure (define proc? (lambda (pc) (procedure? pc))) (define procedure (lambda (var body env) (lambda (val) (value-of body (extend-envvarvalenv))))) (define apply-procedure (lambda (pc val) (pc val))) • procedure? provided from r5rs • Names being bound: • proc? • procedure • apply-procedure • env is an environment • ASTs: body, pc, val, var • Use of procedure? is too liberal. • procedure is not self-contained; takes three arguments: • param name var • body AST • environment
Alternate impl called Closures (define-datatype proc proc? (procedure (var identifier?) (body expression?) (saved-env environment?))) (define apply-procedure (lambda (pc val) (cases proc pc (procedure (var body saved-env) (value-of body (extend-envvarval saved-env)))))) • Defining a new data type called “proc” • Has only one variant • procedure • That has three parts • var • which must be an id • body • an expression • saved-env • an environment • apply-procedure takes pc and val. • “cases proc pc” • pc is expected to be of type proc • code for each variant of proc • only one variant “procedure” here
the data type expval is now … (define-datatypeexpvalexpval? (num-val (num number?)) (bool-val (boolboolean?)) (proc-val (proc proc?)))
value-of: two new clauses (proc-exp (var body) (proc-val (procedure var body env))) (call-exp (rator rand) (let ( (proc (expval->proc (value-of ratorenv))) (arg (value-of rand env))) (apply-procedure proc arg)))
Curried procedures • In PROC, procedures with multiple arguments can be had as in: • let f = proc (x) proc (y) ...in ((f 3) 4) • proc (x) … yields a procedure • Named after Haskell Brooks Curry (1900 – 1982), a combinatory logician.
chapter3/proc-lang/ • Two subdirectories • chapter3/proc-lang/proc-rep: procedural implementation • chapter3/proc-lang/ds-rep: data type based (i.e., closure) • Both directories have the following files • data-structures.scm • drscheme-init.scm • environments.scm • interp.scm • lang.scm • tests.scm • top.scm
EOPL3 Appendix B SLLGEN (define scanner-spec-1 ...) (define grammar-1 ...) (sllgen:make-define-datatypes scanner-spec-1 grammar-1) (define list-the-datatypes (lambda () (sllgen:list-define-datatypes scanner-spec-1 grammar-1))) (define just-scan (sllgen:make-string-scanner scanner-spec-1 grammar-1)) (define scan&parse (sllgen:make-string-parser scanner-spec-1 grammar-1)) (define read-eval-print (sllgen:make-rep-loop "--> " value-of--program (sllgen:make-stream-parser scanner-spec-1 grammar-1))) sllgen:make-define-datatypes: generates a define-datatypefor each production of the grammar, for use by cases. sllgen:make-string-scanner takes a scanner spec and a grammar and generates a scanning procedure read-eval-print loop
Lexical Analysis (define the-lexical-spec '((whitespace (whitespace) skip) (comment ("%" (arbno (not #\newline))) skip) (identifier (letter (arbno (or letter digit "_" "-" "?"))) symbol) (number (digit (arbno digit)) number) (number ("-" digit (arbno digit)) number) )) the-lexical-spec from chapter3/proc-lang/*/lang.scm scanners are specified by reg exp – next slide All our languages use this lexical analysis.
SLLGEN Scanner Spec Scanner-spec ::=({Regexp-and-action}∗) Regexp-and-action ::= (Name ({Regexp}∗) Action) Name ::= Symbol Regexp ::= String | letter| digit| whitespace|any ::= (not Character) | (or {Regexp}∗) ::= (arbnoRegexp) | (concat {Regexp}∗) Action ::= skip | symbol | number | string A scanner specification in SLLGEN is a list that satisfies the grammar at left
The SLLGEN Parsing System (define the-grammar '((program (expression) a-program) (expression (number) const-exp) (expression ("-" "(" expression "," expression ")") diff-exp) (expression ("zero?" "(" expression ")") zero?-exp) (expression ("if" expression "then" expression "else" expression) if-exp) (expression (identifier) var-exp) (expression ("let" identifier "=" expression "in" expression) let-exp) (expression ("proc" "(" identifier ")" expression) proc-exp) (expression ("(" expression expression ")") call-exp) )) the-grammar of PROC from chapter3/proc-lang/*/lang.scm Double-quoted items are terminals/tokens.
Specifying Grammars Grammar ::= ({Production}∗) Production ::= (Lhs ({Ritem}∗) Prod-name) Lhs ::= Symbol Ritem ::= Symbol | String ::= (arbno {Ritem}∗) ::= (separated-list {Ritem}∗ String) Prod-name ::= Symbol A grammar in SLLGEN is a list described by the grammar at left
HW2 Problem (define closure(lambda (ids body env) (let ((freevars (set-diff (free-vars body) ids))) (let ((saved-env (extend-envfreevars (map (lambda (v) (apply-envenvv))freevars) (empty-env)))) (lambda (args) (eval-expression body (extend-env ids args saved-env))))))) • http://www.cs.wright.edu/~pmateti/Courses/784/Top/784-HW2.html • In our data-structure representation of procedures, we have kept the entire environment in the closure. But of course all we need are the bindings for the free variables. • Modify the representation of procedures to retain only the free variables. • flat closure rep shown left • consists of exactly one rib of free variables and their values. • free-vars: ykwim;-) • set-diff: difference of two sets • map provided from r5rs