Bindex: Naming, Free Variables, and Environments SOLUTIONS

Similar documents
Bindex: Naming, Free Variables, and Environments

FOFL and FOBS: First-Order Functions

Valex: Primitive Operators and Desugaring

Valex: Mul*ple Value Types, Condi*onals, Dynamic Type Checking and Desugaring

Hofl: First-class Functions and Scoping

Valex: Mul*ple Value Types, Condi*onals, Dynamic Type Checking and Desugaring SOLUTIONS

CS251 Programming Languages Handout # 36 Prof. Lyn Turbak April 4, 2007 Wellesley College Revised April 14, Scoping in Hofl

Interpre'ng and Compiling Intex SOLUTIONS

Interpre'ng and Compiling Intex

Hofl, a Higher-order Functional Language. 1 An Overview of Hofl. 2 Abstractions and Function Applications

Problem Set 5 Due:??

Interpre'ng and Compiling Intex

Metaprogramming in SML: PostFix and S-expressions

CS301 Compiler Design and Implementation Handout # 18 Prof. Lyn Turbak February 19, 2003 Wellesley College

Metaprogramming in SML: PostFix and S-expressions

CSE 341 Section 5. Winter 2018

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Sum-of-Product Data Types

CS251 Programming Languages Spring 2016, Lyn Turbak Department of Computer Science Wellesley College

PostFix. PostFix command semanccs (except exec) PostFix Syntax. A PostFix Interpreter in Racket. CS251 Programming Languages Fall 2017, Lyn Turbak

Comp 311: Sample Midterm Examination

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Sum-of-Product Data Types

CS115 - Module 10 - General Trees

CS251 Programming Languages Handout # 29 Prof. Lyn Turbak March 7, 2007 Wellesley College

Functional Programming. Pure Functional Programming

Functions & First Class Function Values

COMP520 - GoLite Type Checking Specification

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

The Typed Racket Guide

CSE341 Spring 2017, Final Examination June 8, 2017

Procedures. EOPL3: Section 3.3 PROC and App B: SLLGEN

CS558 Programming Languages

CMSC 330: Organization of Programming Languages

Homework 2 SNU , Fall 2014 Kwangkeun Yi due: 10/07, 24:00

PostFix. PostFix command semanccs (except exec) PostFix Syntax. A PostFix Interpreter in Racket. CS251 Programming Languages Spring 2018, Lyn Turbak

Module 9: Trees. If you have not already, make sure you. Read How to Design Programs Sections 14, 15, CS 115 Module 9: Trees

Bindings & Substitution

Func+on applica+ons (calls, invoca+ons)

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

CS 275 Name Final Exam Solutions December 16, 2016

CS 11 Ocaml track: lecture 7

Recap: Functions as first-class values

CS251 Programming Languages Handout # 47 Prof. Lyn Turbak May 22, 2005 Wellesley College. Scheme

Compilation 2013 Semantic Analysis

Lecture 15 CIS 341: COMPILERS

Environments

Agenda. CS301 Session 9. Abstract syntax: top level. Abstract syntax: expressions. The uscheme interpreter. Approaches to solving the homework problem

Lecture 12: Conditional Expressions and Local Binding

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Lecture 3: Expressions

Mid-Term 2 Grades

CS251 Programming Languages Spring 2016, Lyn Turbak Department of Computer Science Wellesley College

CSE341 Spring 2017, Final Examination June 8, 2017

A Functional Evaluation Model

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

CS 360 Programming Languages Interpreters

List Processing in SML

Sample Exam; Solutions

CS558 Programming Languages

CS2500 Exam 2 Fall 2011

Racket: Modules, Contracts, Languages

Data Abstraction. An Abstraction for Inductive Data Types. Philip W. L. Fong.

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

CS558 Programming Languages

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

CS3110 Spring 2016 Lecture 6: Modules

Outline. What is semantics? Denotational semantics. Semantics of naming. What is semantics? 2 / 21

Inductive Data Types

Jim Lambers ENERGY 211 / CME 211 Autumn Quarter Programming Project 4

CSE 341 Section 7. Ethan Shea Autumn Adapted from slides by Nicholas Shahan, Dan Grossman, Tam Dang, and Eric Mullen

Relation Overriding. Syntax and Semantics. Simple Semantic Domains. Operational Semantics

CSE341, Spring 2013, Final Examination June 13, 2013

CSE341 Autumn 2017, Final Examination December 12, 2017

Module 10: General trees

CS115 - Module 8 - Binary trees

ASTs, Objective CAML, and Ocamlyacc

Metaprogramming assignment 3

CSc 372. Comparative Programming Languages. 4 : Haskell Basics. Department of Computer Science University of Arizona

Principles of Programming Languages

Sum-of-Product (SOP) Datatypes in SML

Mini-ML. CS 502 Lecture 2 8/28/08

List Processing in SML

CSE341 Spring 2017, Midterm Examination April 28, 2017

CSc 372 Comparative Programming Languages. 4 : Haskell Basics

CS 342 Lecture 8 Data Abstraction By: Hridesh Rajan

Type Soundness. Type soundness is a theorem of the form If e : τ, then running e never produces an error

Formal Semantics. Chapter Twenty-Three Modern Programming Languages, 2nd ed. 1

From Syntactic Sugar to the Syntactic Meth Lab:

Lecture 7: The Untyped Lambda Calculus

Begin at the beginning

Typed Racket: Racket with Static Types

9 Objects and Classes

CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter

CSE 341, Spring 2011, Final Examination 9 June Please do not turn the page until everyone is ready.

Homework 3 COSE212, Fall 2018

TAIL RECURSION, SCOPE, AND PROJECT 4 11

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Transcription:

Review: Scope and Lexical Contours Bindex: Naming, Free Variables, and Environments CS251 Programming Languages Fall 2018, Lyn Turbak Department of Computer Science Wellesley College scope = area of program where declared name can be used. Show scope in Racket via lexical contours in scope diagrams. (define add-n (λ ( x ) (+ n x )) ) (define add-2n (λ ( y ) (add-n (add-n y )))) (define n 17) (define f (λ ( z ) (let {[ c (add-2n z ) ] [ d (- z 3) ]} (+ z (* c d ))) ) ) Bindex 2 Review: DeclaraHons vs. References A declarabon introduces an idenhfier (variable) into a scope. A reference is a use of an idenhfier (variable) within a scope. We can box declarahons, circle references, and draw a line from each reference to its declarahon. Dr. Racket does this for us (except it puts ovals around both declarahons and references). An idenhfier (variable) reference is unbound if there is no declarahon to which it refers. Review: Shadowing An inner declarahon of a name shadows uses of outer declarahons of the same name. (let {[x 2]} (- (let {[x (* x x)]} (+ x 3)) x )) Can t refer to outer x here. Bindex 3 Bindex 4

(define (f w z) (* w Review: Alpha-renaming Can consistently rename idenhfiers as long as it doesn t change the connechons between uses and declarahons. (let {[c (add-2n z)] [d (- z 3)]} (+ z (* c d)))))) OK (define (f c d) (* c (let {[b (add-2n d)] [c (- d 3)]} (+ d (* b c)))))) Review: Scope, Free Variables, and Higher-order FuncHons In a lexical contour, an idenhfier is a free variable if it is not defined by a declarahon within that contour. Scope diagrams are especially helpful for understanding the meaning of free variables in higher order funchons. (define (make-sub n ) (λ ( x ) (- x n )) ) Not OK (define (f x y) (* x (let {[x (add-2n y)] [y (- d y)]} (+ y (* x y)))))) Bindex 5 (define (map-scale factor ns ) (map (λ ( num ) (* factor num )) ns) ) Bindex 6 A New Mini-Language: Bindex Bindex adds variable names to Intex in two ways: 1. The arguments of Bindex programs are expressed via variable names rather than posihonally. E.g.: (bindex (a b) (/ (+ a b) 2)) (bindex (a b c x) (+ (* a (* x x)) (+ (* b x) c))) 2. Bindex has a local naming construct (bind I_defn E_defn E_body) that behaves like Racket s (let {[I_defn E_defn]} E_body) (bindex (p q) (bind sum (+ p q) (/ sum 2))) (bindex (a b) (bind a_sq (* a a) (bind b_sq (* b b) (bind numer (+ a_sq b_sq) (bind denom (- a_sq b_sq) (/ numer denom)))))) (bindex (x y) (+ (bind a (/ y x) (bind b (- a y) (* a b))) (bind c (bind d (+ x y) (* d y)) (/ c x)))) Can use bind in any expression posihon Bindex 7 Bindex REPL Interpreter in achon REPL = Read/Eval/Print Loop. Our goal is to see how this all works. - BindexEnvInterp.repl(); bindex> (+ (/ 6 3) ( * 5 8)) 42 bindex> (bind a (+ 1 2) (bind b ( * a 5) (- a b))) ~12 bindex> (#args (num 5) (p 10) (q 8)) bindex> ( * (- q num) p) 30 bindex> (#run (bindex (x y) (+ ( * x x) ( * y y))) 3 4) 25 bindex> (#run (bindex (a b) (bind sum (+ a b) (/ sum 2))) 5 15) 10 bindex> (#quit) Moriturus te saluto! val it = () : unit Try it out: ~/sml/bindex/bindexenvinterp.sml Bindex 8

Bindex Abstract Syntax type ident = string (* introduce ident as synonym for string *) datatype pgm = Bindex of ident list * exp (* param names, body *) and exp = Int of int (* integer literal with value *) Var of ident(* variable reference *) BinApp of binop * exp * exp (* binary application of rator to rand1 & rand2 *) Bind of ident * exp * exp (* bind name to value of defn in body *) and binop = Add Sub Mul Div Rem (* binary arithmetic ops *) val stringtoexp : string -> exp val stringtopgm : string -> pgm val exptostring : exp -> string val pgmtostring : pgm -> string Bindex AST example (bindex (x y) (+ (bind a (/ y x) (bind b (- a y) (* a b))) (bind c (bind d (+ x y) (* d y)) (/ c x)))) - Bindex.stringToPgm "(bindex (a b) (bind sum (+ a b) (/ sum 2)))" val it = Bindex (["a","b"], Bind ("sum",binapp (Add,Var "a",var "b"), BinApp (Div,Var "sum",int 2))) : Bindex.pgm Bindex 9 Bindex 10 CalculaHng Free Variables in Bindex Bindex Lexical Contours and Free Variables Bindex 11 Bindex 12

String sets (similar to PS7 sets, but specialized to strings) signature STRING_SET = sig type t (* The type of a string set *) val empty : t val singleton : string -> t val isempty : t -> bool val size : t -> int val member : string -> t -> bool val insert : string -> t -> t val delete : string -> t -> t val union : t -> t -> t val intersection : t -> t -> t val difference : t -> t -> t val fromlist : string list -> t val tolist : t -> string list val topred : t -> (string -> bool) val tostring : t -> string structure StringSetList :> STRING_SET = struct (* See ~wx/sml/utils/stringset.sml for details *) Bindex 13 Bindex: Code for handling free variables structure S = StringSetList (* val freevarspgm : pgm -> S.t *) (* Returns the free variables of a program *) fun freevarspgm (Bindex(fmls,body)) = S.difference (freevarsexp body) (S.fromList fmls) (* val freevarsexp : exp -> S.t *) (* Returns the free variables of an expression *) and freevarsexp (Int i) = S.empty freevarsexp (Var name) = S.singleton name freevarsexp (BinApp(_,rand1,rand2)) = S.union (freevarsexp rand1) (freevarsexp rand2) freevarsexp (Bind(name,defn,body)) = S.union (freevarsexp defn) (S.difference (freevarsexp body) (S.singleton name)) (* val freevarsexps : exp list -> S.t *) (* Returns the free variables of a list of expressions *) and freevarsexps exps = foldr (fn (s1,s2) => S.union s1 s2) S.empty (map freevarsexp exps) (* val varcheck : pgm -> bool *) and varcheck pgm = S.isEmpty (freevarspgm pgm) Bindex 14 Environments bind names to values signature ENV = sig type 'a env val empty: 'a env val bind : string -> 'a -> 'a env -> 'a env val bindall : string list -> 'a list -> 'a env -> 'a env val make : string list -> 'a list -> 'a env val lookup : string -> 'a env -> 'a option val map: ('a -> 'a) -> 'a env -> 'a env val remove : string -> 'a env -> 'a env val removeall : string list -> 'a env -> 'a env val merge : 'a env -> 'a env -> 'a enve structure Env :> ENV = struct (* See ~wx/sml/utils/env.sml for details *) Environment Examples - val env0 = Env.make ["a", "b"] [7, 3] val env0 = - : int Env.env - Env.lookup "a" env0; val it = SOME 7 : int option - Env.lookup "b" env0; val it = SOME 3 : int option - Env.lookup "c" env0; val it = NONE : int option - val env1 = Env.bind "sum" 10 env0; val env1 = - : int Env.env - Env.lookup "sum" env1; val it = SOME 10 : int option - Env.lookup "sum" env0; val it = NONE : int option - Env.lookup "a" env1; val it = SOME 7 : int option env1 env0 a b sum 10 - Env.lookup "d" env2; val it = SOME 17 : int option - Env.lookup "b" env2; val it = SOME 42 : int option - Env.lookup "a" env2; val it = SOME 7 : int option 7 3 b d env2 42 17 Bindex 15 - val env2 = Env.bindAll ["b", "d"] [42, 17] env0; val env2 = - : int Env.env Bindex 16

Bindex EvaluaHon Example env0 x 3 y 6 Environments follow contours! -8 10 env1 a 2 env2 b -4 18 env4 d 9 env3 c 54 o For each contour C_i, there is a corresponding environment env_i that binds the variables in C_i o If C_k is nested directly inside of C_j, environment frame env_k has frame env_j as its parent env0 x 3 y 6 2-8 54 18 env1 a 2 env4 d 9 env3 c 54 6 3-4 -8 9 54 54 3 env2 b -4 2 6 2-4 3 6 9 6 Bindex 17 Bindex 18 open Bindex exception EvalError of string Bindex Interpreter (* val run : Bindex.pgm -> int list -> int *) fun run (Bindex(fmls,body)) ints = let val flen = length fmls val ilen = length ints in if flen = ilen then eval body (Env.make fmls ints) else raise (EvalError ("Program expected " ^ (Int.toString flen) ^ " arguments but got " ^ (Int.toString ilen))) (* val eval : Bindex.exp -> int Env.env -> int *) and eval (Int i) env = i eval (Var name) env = (case Env.lookup name env of SOME(i) => i NONE => raise (EvalError("Unbound variable: " ^ name))) eval (BinApp(rator,rand1,rand2)) env = (binoptofun rator)(eval rand1 env, eval rand2 env) eval (Bind(name,defn,body)) env = eval body (Env.bind name (eval defn env) env) BindexEnvInterp examples - eval (stringtoexp "(/ y x)") env0; val it = 2 : int - val env1 = Env.bind "a" 2 env0; val env1 = - : int Env.env - eval (stringtoexp "(- a y)") env1; val it = ~4 : int - val env2 = Env.bind "b" ~4 env1; val env2 = - : int Env.env - eval (stringtoexp "(* a b)") env2; val it = ~8 : int - eval (stringtoexp "(+ x y)") env0; val it = 9 : int - val env4 = Env.bind "d" 9 env0; val env4 = - : int Env.env - eval (stringtoexp "(* d y)") env4; val it = 54 : int - val env3 = Env.bind "c" 54 env0; val env3 = - : int Env.env - eval (stringtoexp "(/ c x)") env3; val it = 18 : int - eval (stringtoexp "(bind a (/ y x) (bind b (- a y) (* a b)))") env0; val it = ~8 : int - eval (stringtoexp "(bind c (bind d (+ x y) (* d y)) (/ c x))") env0; val it = 18 : int - runfile "scope.bdx" [3,6]; val it = 10 : int (* val binoptofun : Bindex.binop -> (int * int) -> int *) (* This is unchanged from the Intex interpreter *) Bindex 19 - run (stringtopgm "(bindex (a b) (bind sum (+ a b) (/ sum 2)))") [7,3]; val it = 5 : int Bindex 20

Exting Bindex: Sigmex = Bindex + sigma Sigmex: sigma examples Bindex 21 Bindex 22 Sigmex: Parsing/unparsing sigma expression from/to S-expressions datatype pgm = Sigmex of ident list * exp (* param names, body *) and exp = Int, Var, BinApp, Bind from Bindex Sigma of ident * exp * exp * exp (* E_lo, E_hi, E_body *) (* val sexptoexp : Sexp.sexp -> exp *) and sexptoexp (Sexp.Int i) = Int i other clauses for Bindex sexptoexp (Seq [Sym "bind", Sym name, defnx, bodyx]) = Bind (name, sexptoexp defnx, sexptoexp bodyx) (* Figure out parsing of sigma below by analogy with bind above *) sexptoexp (Seq [Sym "sigma", Sym name, lox, hix, bodyx]) = Sigma(name, sexptoexp lox, sexptoexp hix, sexptoexp bodyx) (* val exptosexp : exp -> Sexp.sexp *) and exptosexp (Int i) = Sexp.Int I other clauses for Bindex exptosexp (Bind(name, defn, body)) = Seq [Sym "bind", Sym name, exptosexp defn, exptosexp body] (* Figure out unparsing of sigma below by analogy with bind above *) exptosexp (Sigma(name, lo, hi, body)) = Seq [Sym "sigma", Sym name, exptosexp lo, exptosexp hi, exptosexp body] Bindex 23 Sigmex: free vars of sigma expression Free variable rule: Bindex Phrase P (sigma I E_lo E_hi E_body) Free Variables: FV(P) FV(E_lo) U FV(E_hi) U (FV(E_body) {I}) Expressing sigma free variable rule in Sigmex program: datatype pgm = Sigmex of var list * exp (* param names, body *) and exp = Int, Var, BinApp, Bind from Bindex Sigma of var * exp * exp * exp (* E_lo, E_hi, E_body *) (* val freevarsexp : exp -> S.t *) and freevarsexp (Int i) = S.empty other clauses for Bindex freevarsexp (Bind(name,defn,body)) = S.union (freevarsexp defn) (S.difference (freevarsexp body) (S.singleton name)) freevarsexp (Sigma(name,lo,hi,body)) = S.union (freevarsexp lo) (S.union (freevarsexp hi) (S.difference (freevarsexp body) (S.singleton name))) Bindex 24

Sigmex: sigma evaluahon How should the following sigma expression be evaluated in an environment env1 = a 2, b 3? (sigma j (+ a 1) (* a b) (+ a (* b j))) # env1 * (sigma j 3 6 (+ a (* b j)) # env1 Sum up the following: (+ a (* b j)) # j 3, env1 (+ a (* b j)) # j 4, env1 (+ a (* b j)) # j 5, env1 (+ a (* b j)) # j 6, env1 * (+ 11 (+ 14 (+ 17 (+ 20 0)))) # env1 * 62 # env1 Sigmex: sigma evaluahon clause datatype pgm = Sigmex of var list * exp (* param names, body *) and exp = Int, Var, BinApp, Bind from Bindex Sigma of var * exp * exp * exp (* E_lo, E_hi, E_body *) (* val eval : Sigmex.exp -> int Env.env -> int *) and eval other clauses from bindex eval (Bind(name,defn,body)) env = eval body (Env.bind name (eval defn env) env) eval (Sigma(name, lo, hi, body)) env = let val vlo = eval lo env val vhi = eval hi env val ints = Utils.range vlo (vhi + 1) val vals = List.map (fn i => eval body (Env.bind name i env)) ints in List.foldr op+ 0 vals (* could use foldl instead *) Bindex 25 Bindex 26