Presentation on theme: "THE WORKER / WRAPPER TRANSFORMATION Graham Hutton and Andy Gill."— Presentation transcript:
THE WORKER / WRAPPER TRANSFORMATION Graham Hutton and Andy Gill
1 What Is It? program wrapper worker A technique for changing the type of a program in order to improve its performance:
2 This Talk zTechnique has been used by compiler writers for many years, e.g. GHC since 1991; zBut is little known in the wider community, and has never been described precisely; zWe explain, formalise and explore the generality of the worker/wrapper transformation.
3 Fixed Points ones = 1 : ones ones = fix body body xs = 1 : xs can be rewritten as: fix f = f (fix f) The key to formalising the technique is the use of explicit fixed points. For example:
4 The Problem A Type of the desired worker. Type of the original program. B Suppose we wish to change the type of a recursive program, defined by prog = fix body.
5 Assumptions We assume conversion functions A can be faithfully represented by B. such that: wrap. unwrap = id A AB wrap unwrap
6 Let’s Calculate! 6 prog fix body = fix (wrap. unwrap. body) = fix (id A. body) = wrap work = wrap (fix (unwrap. body. wrap)) = Rolling rule.
7 Summary prog We have derived the following factorisation: Wrapper of type B A. Recursive program of type A. wrap = Recursive worker of type B. work
8 The Final Step We simplify work = fix (unwrap. body. wrap) unwrapwrap and to eliminate the overhead of repeatedly converting between the two types, by fusing together
9 The Worker / Wrapper Recipe ① Express the original program using fix; ② Choose the new type for the program; ③ Define appropriate conversion functions; ④ Apply the worker/wrapper transformation; ⑤ Simplify the resulting definitions.
10 Example - Reverse How can we improve: rev  =  rev (x:xs) = rev xs ++ [x] Step 1 - express the program using fix rev = fix body body f  =  body f (x:xs) = f xs ++ [x] Quadratic time.
11 Step 2 - choose a new type for the program [a] [a] [a] abs rep where rep xs = (xs ++) abs f = f  Key idea (Hughes): represent the result list as a function.
12 Step 3 – define conversion functions [a] [a] wrap unwrap where unwrap f = rep. f wrap g = abs. g Satisfies the worker/wrapper assumption. [a] [a] [a]
13 Step 4 – apply the transformation rev = wrap work work = fix (unwrap. body. wrap) Step 5 – simplify the result rev :: [a] [a] rev xs = work xs  Expanding out wrap.
14 Using properties of rep and Worker/wrapper fusion property. we obtain a linear time worker: work :: [a] [a] [a] work  ys = ys work (x:xs) ys = work xs (x:ys) unwrap (wrap work) work =
15 Notes zOnce the decision to use Hughes lists is made, the derivation itself is straightforward; zNo induction is required, other than the implicit use to verify that lists form a monoid; zFast reverse fits naturally into our paradigm, but simpler derivations are of course possible.
16 Example - Unboxing Int Int More efficient worker that uses unboxed integers. Type of a simple factorial function. Int ♯ Int ♯ Note: this is how GHC uses worker/wrapper.
17 Example - Memoisation More efficient worker that uses a memo table. Type of a simple Fibonacci function. Nat Nat Stream Nat
18 Example - Continuations Expr Mint More efficient worker that uses success and failure continuations. Type of a simple evaluation function that may fail, where Mint = Maybe Int. Expr (Int Mint) Mint Mint
19 Summary zGeneral technique for changing the type of a program to improve its performance; zStraightforward to understand/apply, requiring only basic equational reasoning principles; zCaptures many seemingly unrelated optimisation methods in a single unified framework.
20 Further Work zMechanising the technique; zSpecialised patterns of recursion; zGeneralisation using category theory; zPrograms with effects; zOther application areas.