today
play

Today Translating our parsing rules to Haskell Lambda Calculus - PowerPoint PPT Presentation

Today Translating our parsing rules to Haskell Lambda Calculus Higher-Order abstract syntax A more formal definition of substitution What is an embedded language? Exercises & more Haskell (on demand) s L s 1 N s 2 L


  1. Today • Translating our parsing rules to Haskell • Lambda Calculus • Higher-Order abstract syntax • A more formal definition of substitution • What is an embedded language? • Exercises & more Haskell (on demand)

  2. s L s 1 N s 2 L (L-1) (L-2) (N-1) s 1 s 2 L ε L ( s ) N * e 1 PExpr e 2 SExpr e PExpr e 1 Pxpr ↔ e 1 ’ expr e 2 xpr ↔ e 2 ’ expr ↔ e’ expr e 1 + e 2 SExpr e SExpr ↔ e’ expr e 1 + e 2 SExpr ↔ ( Plus e 1 ’ e 2 ’ ) expr e 1 FExpr ↔ e 1 ’ expr e 2 PExpr ↔ e 2 ’ expr e 1 PExpr ↔ e 1 ’ expr e 2 FExpr ↔ e 2 ’ expr ↔ e’ expr e FExpr ↔ e’ expr e 1 * e 2 PExpr ↔ (Times e 1 ’ e 2 ’ ) expr e 1 * e 2 PExpr ↔ (Times e 1 ’ e 2 ’ ) expr e PExpr e SExpr ↔ e’ expr i ∈ Int i FExpr ↔ ( Num i ) expr ( e ) FExpr ↔ e’ expr * these rules don’t reflect associativity correctly

  3. λ -Abstractions • Example: mapping a function over lists map even [1,2,3,4] = [False, True, False, True] map (3+) [1,2,3,4] = [4,5,6,7] map (/2) [2,4,6,8] = [1,2,3,4] let f x = x * x + 5 in map f [1,2,3,4] = [6,9,14,21] map (\x -> x * x + 5) [1,2,3,4] (\x -> x * 2) 10 = 20 let f = \x -> x * x + 5 in map f [1,2,3,4]

  4. λ -Abstractions map (\(x,y) -> (x + y)/2) [(4,6), (2,4), (1,7)] = [5,3,4] zipWith (\x -> \y -> (x + y)/2) [4,2,1] [6,4,7] = [5,3,4] zipWith (\x y -> (x + y)/2) [4,2,1] [6,4,7] = [5,3,4] • ‘\’ is read as λ (lambda) 
 • λ -expressions are supported by now in many non-functional languages

  5. The untyped λ -Calculus • Introduced in the 1936 by mathematician Alonzo Church • Very simple, Turing-complete formalism for computations • λ -terms: t λ -term id ∈ Ident id λ -term λ id . t λ -term t λ -term s λ -term ( t s ) λ -term

  6. The untyped λ -Calculus • The calculus has three rules: ‣ α -conversion - if t ≡ α s, then the two terms are equivalent in the calculus • λ x . λ y . y ≡ α λ y . λ x . x ≡ α λ a λ b . b ‣ β -reduction - ( λ x . t ) s can be reduced to t[x:=s] • ( λ x . λ y . y) ( λ a . a) → β λ y . y • ( λ x . λ y . x) ( λ a . a) → β λ y . λ a . a • ( λ x . x + 1) 5 → β 5 + 1 ‣ η -conversion - λ x . (f x ) is equivalent to f if x is not free in f • λ x . (( λ z . z + 1) x ) ≡ η ( λ z . z + 1)

  7. The untyped λ -Calculus • How can boolean values be encoded in the calculus? ‣ True: λ x. λ y.x ‣ False: λ x. λ y.y ‣ If: λ c. λ t. λ e.c t e

  8. The untyped λ -Calculus • Natural numbers, arithmetic, logic operations ‣ 0 := λ f. λ x.x ‣ 1 := λ f. λ x.(f x) ‣ 2 := λ f. λ x.(f (f x)) ‣ 3 := λ f. λ x.(f (f (f x))) ‣ successor (+1): λ n. λ f. λ x.(f ((n f) x)) ‣ addition (+): λ m. λ n. λ f. λ x.(m f (n f x)) ‣ multiplication(+): λ m. λ n. λ f. λ x. (m (n f ) x) ‣ predecessor : λ n. λ f. λ x.(n ( λ g. λ h.h (g f))( λ u. x) ( λ u.u))

  9. The untyped λ -Calculus ‣ predecessor is complicated - here is the computation for “pred 1”: λ n. λ f. λ x.(n ( λ g. λ h.h (g f))( λ u.x)( λ u.u))( λ f. λ x. f x) ≡ η λ n. λ f. λ x.(n ( λ g. λ h.h (g f))( λ u.x)( λ u.u)) ( λ f.f) → β → β λ f. λ x.(( λ f.f) ( λ g. λ h.h (g f))( λ u.x)( λ u.u)) → β λ f. λ x.(( λ g. λ h.h (g f))( λ u.x)( λ u.u)) → β λ f. λ x.(( λ h.h (( λ u.x) f))( λ u.u)) λ f. λ x.(( λ h.h x)( λ u.u)) → β → β λ f. λ x.(( λ u.u) x) λ f. λ x.x (the argument of each beta-reduction step is coloured green, the binding and usage occurrences of the variable substituted is red)

  10. Higher-order abstract syntax • A problem with (first-order) abstract syntax (Num i ) expr t 1 expr t 2 expr (Times t 1 t 2 ) expr id Ident (Var id) expr t 1 expr t 2 expr (Let id t 1 t 2 ) expr (Var id ) expr • Defining and usage occurrence of variables are treated the same ‣ abstract syntax doesn’t di ff erentiate between binding and using occurrence of a variable ‣ it’s di ffi cult to identify α -equivalent expressions ‣ variables are just terms, like numbers

  11. Higher-order abstract syntax • Higher-order abstract syntax has variables and abstraction as special constructs • A term of the form x.t is called an abstraction • Structure of a higher-order term: a higher-order term can have one of four forms: (1) a constant (e.g., int, string) (2) a variable x (3) (Operator t 1 ... t n ) ‣ Num 4 ‣ Plus x (Num 4) (4) x.t (i.e., the variable x is bound in term t ) ‣ x. Plus x (Num 1) ‣ x.y. Plus x y

  12. Higher-order abstract syntax • Higher-order abstract syntax for let-expressions id Ident var(id) expr t 1 expr t 2 expr first-order (Let id t 1 t 2 ) expr (Var id) expr id Ident t 1 expr t 2 expr higher-order (Let t 1 id . t 2 ) expr id expr • Mapping of concrete to higher-order syntax e 1 SExpr ↔ t 1 expr e 2 SExpr ↔ t 2 expr let id = e 1 in e 2 end SExpr ↔ ( Let t 1 id.t 2 ) expr id Ident id FExpr ↔ id expr • Example: let x = 5 in x+y SExpr ↔ (Let (Num 5) (x.Plus x y)) expr

  13. Substitution Definition: A notation for substitution We write t[x:=t’] to denote a term t where all the free occurrences of x have been replaced by the term t’ . • Example: (Plus x y) [x :=(Num 1)] = (Plus (Num 1) y) Definition: Renaming If we replace a variable in the binding and the body of an abstraction, it is called renaming, and the resulting term is α -equivalent to the original term: x.t ≡ α y.t [x:= y] if y doesn’t occur free in t (or y ∉ FV (t))

  14. Substitution • A inductive definition of FV(t) : FV (x) = {x} FV (Op t1 ... tn) = FV(t1) ∪ .... ∪ FV(tn) FV (x.t) = FV(t) \ {x} • Substituting one variable by another: x[x:=y] = y z[x:=y] = z, if z ≠ x (Op t 1 ... t n ) [x:=y] = Op (t 1 [x:=y]) ... (t n [x:=y]) x.t [x:=y] = x.t z.t [x:=y] = z. (t [x:=y]), if x ≠ z, y ≠ z y.t [x:=y] = undefined, if x ≠ y

  15. Substitution • Substituting a variable by a term u: x [x:=u] = u z [x:=u] = z, if z ≠ x (Op t 1 ... t n ) [x:=u] = Op (t 1 [x:=u]) ... (t n [x:=u]) x.t [x:=u] = x.t z.t [x:=u] = z. (t [x:=u]), if x ≠ z, z ∉ FV(u) y.t [x:=u] = undefined, if y ∈ FV(u)

  16. Domain Specific Embedded Languages • Instead of designing and developing language from scratch, add domain specific instructions via library to host language • There are two ways to embed a language - shallow embedding - deep embedding

  17. Shallow Embedding • Shallow embedding provides fixed interpretation • Semantics captured in the type • Example: arithmetic expression language type Expr = Float add :: Expr -> Expr -> Expr add e1 e2 = e1 + e2 mult :: Expr -> Expr -> Expr mult e1 e2 = e1 * e2 neg :: Expr -> Expr neg e = -1 * e sampleExpr :: Expr sampleExpr = neg (mult (add 2 3) 5)

  18. DEEP EMBEDDING • Captures DSL expression as abstract syntax tree (AST), allowing multiple interpretations data Expr = Num Int | Var String | Plus Expr Expr | Times Expr Expr | LetBnd Ident Expr Expr

  19. Project • Deeply embedded language • Concrete syntax is not of concern for us - in real EDSLs, constructors usually wrapped in smart constructors • Possibilities: - graphics description language - text layout, html - scripting language - can either generate code (of your choice), or interpret it in Haskell

Recommend


More recommend