1 / 14

A Staged Semantics of Overloading (preliminary)

A Staged Semantics of Overloading (preliminary). Bill Harrison & Tim Sheard. 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])

monifa
Download Presentation

A Staged Semantics of Overloading (preliminary)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 -> <Dynam Value> • Inlining semantics inline :: E -> S <Dynam Value> • Runtime updatable semantics pr :: E -> S <Dynam Value>

  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) => <mkread ~(lift x)> where fun mkread x = Do d { (Env rho) <- rdEnv ; (rho x) }; (const (tag,_)) => case tag of "zero" => <Return d (Z 0)> | "one" => <Return d (Z 1)> <mkfun "x" (mkread "x")> : <Value D>

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

  12. Example For function foo: foo :: Eq a => a -> Bool foo x = ([x]==[x]) Produces the following if “a” is Integer: -| inlineshow foo Integer; val it = <mkfun "x" (mkeq (eqList eqInteger) (mkread "x") (mkread "x"))> : <Value D>

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

  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) (mkbinop addInt (Return d Z 1) (Return d Z 1))))) }> : <Value D>

More Related