Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Staged Semantics of Overloading (preliminary) Bill Harrison & Tim Sheard.

Similar presentations


Presentation on theme: "A Staged Semantics of Overloading (preliminary) Bill Harrison & Tim Sheard."— Presentation transcript:

1 A Staged Semantics of Overloading (preliminary) Bill Harrison & Tim Sheard

2 Related Work Making Ad Hoc Polymorphism Less Ad Hoc, (Wadler & Blott[1989],…) Source to source “dictionary-passing transformation” Dictionary-free Overloading by Partial Evaluation (Jones[1995]) Resolves overloading by inlining methods Avoids source transformation, but fails for polymorphic recursion Metacomputation-based Compiler Architecture (Harrison&Kamin[2000]) Introduces denotational model of staging Two-monad approach (Static ; Dynam)

3 Today Show how techniques in staged semantics apply to overloading Simple language E: terms of type (Eq a,Num a) =>… Not claiming to have Haskell nailed, but… Compelling examples including polymorphic recursion Methodology: Annotate some source terms with type information Namely, “==“, arith., and poly-rec. applications all (plausibly) derivable from a type derivation Idea: Given binding for “a”, First stage resolves overloading statically (if possible) Second stage may uses type info to update “==“ No dictionaries: either inlining or runtime update Three definitions in MetaML: reference, inlining, and runtime updating definitions

4 Avoiding Dictionary Passing Translation Try inlining? I.e., for any instance of a in: replace “==“ by a specific equality operation Ex: (\ x -> [x]==[x]) :: Eq a => a -> Bool (\ x -> [x] `eqInt` [x]) :: Int -> Bool advantage: can be accomplished via meaning-preserving process: partial evaluation

5 Why polymorphic recursion complicates the problem Consider the poly-rec. Haskell function “weird” weird :: Eq a => a -> Bool weird x = x==x && (weird [x]) applied at a applied at [a] At runtime, a poly-rec. function may require  “==”s

6 Outline of Talk Source language E Reference semantics: usual monadic def’n of E. mng :: E -> Inlining semantics inline :: E -> S Runtime updatable semantics pr :: E -> S

7 Source Language E datatype Type = Integer | Real | Bool | Arrow of (Type * Type) | List of Type | Pair of (Type * Type) | TV of Name ; datatype BinOp = Add | Mul | Sub | And; datatype E = lambda of Name*E | app of E*E | var of Name | ite of (E * E * E) | letrec of (Name * E * E) | nilexp | cons of (E * E) | pair of (E * E) | equal of (E * E * Type) | binop of (BinOp * E * E * Type) | const of (Name * Type) | prapp of (E * E * Type); Interesting stuff involves overloaded terms

8 Reference semantics Uses “dynamic” monad D Non-proper morphisms: datatype 'a D = D of (Env -> 'a) and Env = Env of (Name -> Value D) and Value = Z of int | R of real | B of bool | L of (Value list) | P of (Value * Value) | Fun of (Value D -> Value D) | EqOp of (Value -> Value -> Value); rdEnv :: D Env inEnv :: Env -> D a -> D a xEnv :: Env -> Name -> D a -> D a

9 Reference semantics (cont’d) (mng e) defined mostly in terms of “standard” operations: But, there’s no overloading: Ex: (mng (lambda ("x",(var "x"))) produces: fun mng e = case e of (var x) => (const (tag,_)) => case tag of "zero" => | "one" => fun mkread x = Do d { (Env rho) <- rdEnv ; (rho x) }; where :

10 The “static” monad S S includes type environment and “Maybe” effects Type annotations may have variables Resolving overloading may fail for some “a” Improper morphisms Idea: using binding for “a”, Use Type annotations in terms to calculate specific operations And inline them in the result rdTypeEnv :: S TypeEnv inTypeEnv :: TypeEnv -> S a -> S a errMsg :: String -> S a

11 Inlining semantics Stage mng by including a static S phase (inline e) works in S to produce D-computation Unannotated definitions are similar: Overloaded terms: inline :: E -> S fun inline e = case e of (var x) => Return s (equal (e1,e2,t)) => Do s { phi1 <- inline e1 ; phi2 <- inline e2 ; equality <- calcEqOp t ; Return s } Where ~equality will be an (monomorphic) equality operator like: val eqInteger = fn (Z i) => fn (Z j) => B (i=j);

12 Example foo :: Eq a => a -> Bool foo x = ([x]==[x]) For function foo: -| inlineshow foo Integer; val it = : Produces the following if “a” is Integer:

13 Example for third definition let weird x = x==x && (weird [x]) in (weird 3) Consider this term (here using Haskell concrete syntax) weird :: Eq a => a -> Bool weird x = x==x && (weird [x]) Recall: Third semantic definition: pr :: E -> S

14 Dynamic Part of “weird” <Do d { rhoInit <- rdEnv --- initial eq. oper. ; inEnv (xEnv rhoInit "==" (Return d (EqOp eqInteger))) (mkletrec "weird" --- letrec weird =… (mkfun "x" (mkbinop andBool (deltaEqOp (TV "a") --- x==x (Do d { Env b <- rdEnv ; EqOp c <- b "==" ; mkeq c (mkread "x") (mkread "x") })) (deltaEqOp (List (TV "a")) --- weird [x] (mkapp (mkread "weird") (mkcons (mkread "x") mknil))))) (mkapp (mkread "weird") --- in (weird 3) (mkbinop addInt (Return d Z 1) (Return d Z 1))))) }> :


Download ppt "A Staged Semantics of Overloading (preliminary) Bill Harrison & Tim Sheard."

Similar presentations


Ads by Google