440 likes | 622 Views
Syntax With Binders. COS 441 Princeton University Fall 2004. Quick Review About Binding. Difference between bound and free variables x . ( x + y ) -equivalence x. x = y. y Capture avoiding substitution (( x.(x + y)) x) ! (( z. (z + y)) x) ! z. (x + y).
E N D
Syntax With Binders COS 441 Princeton University Fall 2004
Quick Review About Binding • Difference between bound and free variables x. (x + y) • -equivalence x. x = y. y • Capture avoiding substitution (( x.(x + y)) x) ! (( z. (z + y)) x) ! z. (x + y)
Binding in General • Generalize the rules about binding and substitutions for the -calculus to cover other programming languages that uses binding • Harper introduces the general notion of an abstract binding trees (ABTs) • ABTs generalize what we know about abstract syntax trees (ASTs)
ASTs vs ABTs • ASTs do not describe binding or scope of variables • Both defined by signature that maps operators to arities • AST arity is just a natural number • ABT arity sequence of valences • Every AST is an ABT
Encoding Binders with ASTs let(x1,num[1], let(x2,num[2], plus(var[x1],var[x2]))) let val x = 1 val y = 2 in x + y end Abstract Syntax Tree Concrete Syntax
Equality of ASTs The AST below are not equal let(x1,num[1], let(x2,num[2], plus(var[x1],var[x2]))) let(x2,num[1], let(x1,num[2], plus(var[x2],var[x1])))
Encoding Binders with ABTs name abstractor
Encoding Binders with ABTs let(num[1],x1. let(num[2],x2. plus(x1,x2))) let val x = 1 val y = 2 in x + y end Abstract Binding Tree Concrete Syntax
-Equality of ABTs The ABTs below are -equal let(num[1],x1. let(num[2],x2. plus(x1,x2))) let(num[1],x2. let(num[2],x1. plus(x2,x1)))
V Xname X exp E1exp E2exp Xname Eexp A L apply(E1,E2)exp lam(X.E)exp Pure -calculus as an ABT
Free Names in -calculus FN(apply(F,lam(X.X)))
Free Names in -calculus FN(apply(F,lam(X.X))) FN(F) [FN(lam(X.X))
Free Names in -calculus FN(apply(F,lam(X.X))) FN(F) [FN(lam(X.X)) {F} [ (FN(X) nFN(X))
Free Names in -calculus FN(apply(F,lam(X.X))) FN(F) [FN(lam(X.X)) {F} [ (FN(X) nFN(X)) {F} [ ({X} n {X})
Free Names in -calculus FN(apply(F,lam(X.X))) FN(F) [FN(lam(X.X)) {F} [ (FN(X) nFN(X)) {F} [ ({X} n {X}) {F} [ {} {F}
Capture Avoiding Substitution • Capture avoid substitution defined using two other relations • The first is apartness E1#E2 when FN(E1) ÅFN(E2) = {} The unbound variables of terms are distinct • The swapping of one name for another [X$Y] E
Swapping Names in -calculus [X$Y] lam(X.lam(Y.apply(X,Z)) lam(Y.lam(X.apply(Y,Z))
Swapping Names in -calculus [X$Y] lam(X.lam(Y.apply(X,Z)) ??
Swapping Names in -calculus [X$Z] lam(X.lam(Y.apply(X,Z)) ??
Swapping Names in -calculus [X$Z] lam(X.lam(Y.apply(X,Z)) lam(Z.lam(Y.apply(Z,X))
Induction Principle for ABTs • Induction principle for ABT slightly more complex • Two different induction hypotheses • P(E) for raw ABT • PA(n,E) for ABT abstractor of valence n • Induction principle lets us rename bound variable names at will • Technicalities are not so important for this course
ABTs in SML • ASTs can easily be encoded directly in SML with datatype • Unfortunately there is no good direct encoding of ABTs into SML • Must first encode ABT as an AST • Globally rename all names to avoid conflicts • Active area of research to provided better programming language support • See http://www.freshml.org
Why Learn About ABTs • Lack of direct support of ABTs in SML is annoying • ABTs are a useful abstraction when specifying programming languages • All scoping and renaming rules come built in with the semantics of ABT • Rigorous theory of induction for ABTs
V Xname X exp E1exp E2exp Xname Eexp A L apply(E1,E2)exp lam(X.E)exp Pure -calculus as an ABT
V Xname var[X] exp E1exp E2exp Xname Eexp A L apply(E1,E2)exp lam(X,E)exp Pure -calculus as an AST
Pure -calculus in SML type name (* abstract type *)
Pure -calculus in SML type name (* abstract type *) datatype exp = Lam of (name * exp) | Apply of (exp * exp) | Var of (name) val eq_alpha : (exp * exp) -> bool val subst : (var * exp * exp) -> exp val free_vars : exp -> var list
Pure -calculus in SML type name (* abstract type *) datatype exp = Lam of (name * exp) | Apply of (exp * exp) | Var of (name) val fresh : unit -> name val name_eq : (name * name) -> bool val alpha_cvt : exp -> exp val subst : (name * exp * exp) -> exp
Static Semantics • Before we can define the precise meaning of a program we must rule non-sense programs • The meaning of a program is only defined for well-formed programs • Example: A program is well-formed if it contains no free names
ok-V X2 ` X ok ` E1ok ` E2ok [{X}` Eok X ok-A ok-L ` apply(E1,E2)ok ` lam(X.E)ok Static Semantics for -calculus
Syntax Directed Rules • The ok relation is syntax directed • Exactly one rule for each case of the abt • Syntax directed rules guarantee goal-directed search always succeeds or fails • Won’t get into infinite loop • Either find a derivation or find out something is not derivable • Syntax directed rules are easier to implement in SML
Syntax Directed Rules (cont.) • A set of rules is syntax directed with respect to a certain set of syntax trees • If for every derivable judgment there is a unique derivation tree that mirrors the original syntax tree • Definition of syntax directed is a bit vague but basically means goal directed search is easy to carry out
Static Semantics/Type Checking • The relation ` E ok is very simple and only to illustrate a general pattern we will see later • We will define a more interesting relation • ` E : T where T is the type of the expression • Well typed programs will be free from certain runtime errors • We must define a semantics of program execution to understand what that means precisely • Next lecture will be about program execution