Scrap Your Boilerplate /~simonpj/papers/hmap/

Slides:



Advertisements
Similar presentations
Sml2java a source to source translator Justin Koser, Haakon Larsen, Jeffrey Vaughan PLI 2003 DP-COOL.
Advertisements

The Art of Avoiding Work
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  Elements may appear more than once.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
Templates in C++. Generic Programming Programming/developing algorithms with the abstraction of types The uses of the abstract type define the necessary.
Kathleen Fisher cs242 Reading: “A history of Haskell: Being lazy with class”,A history of Haskell: Being lazy with class Section 6.4 and Section 7 “Monads.
0 PROGRAMMING IN HASKELL Chapter 10 - Declaring Types and Classes.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
0 LECTURE 5 LIST COMPREHENSIONS Graham Hutton University of Nottingham.
© The McGraw-Hill Companies, 2006 Chapter 8 Extending classes with inheritance.
0 PROGRAMMING IN HASKELL Chapter 7 - Higher-Order Functions.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Good Advice for Type-directed Programming Aspect-oriented Programming and Extensible Generic Functions Geoffrey Washburn [ ] Joint.
0 PROGRAMMING IN HASKELL Chapter 6 - Recursive Functions Most of this should be review for you.
Scrap your boilerplate with class Ralf Lämmel, Simon Peyton Jones Microsoft Research.
Advanced Programming Andrew Black and Tim Sheard Lecture 4 Intro to Haskell.
Chapter 5 Polymorphic and Higher-Order Functions.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 5 Types Types are the leaven of computer programming;
Templates. Objectives At the conclusion of this lesson, students should be able to Explain how function templates are used Correctly create a function.
(c) University of Washington03-1 CSC 143 Java Inheritance Reading: Ch. 10.
Playing with Haskell Data Neil Mitchell. Overview The “boilerplate” problem Haskell’s weakness (really!) Traversals and queries Generic traversals and.
Functional Programming Lecture 4 - More Lists Muffy Calder.
Tuples and Lists Lecture 3, Programmeringsteknik del A.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Haskell programming language. Haskell is… Memory managed (allocation, collection) “Typeful” (static, strong) – Types are checked at compile-time – Types.
0 REVIEW OF HASKELL A lightening tour in 45 minutes.
Variables and Functions. Open your Encoder program Let’s begin by opening the “Labyrinth Auto Straight” code. Save this file as Labyrinth with variables.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Types and Classes Dr. Hyunyoung Lee.
0 PROGRAMMING IN HASKELL Chapter 9 - Higher-Order Functions, Functional Parsers.
Modeling with Haskell Scientific Seminar 03/04 Gerhard Navratil.
1 Functional Programming Lecture 6 - Algebraic Data Types.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L13-1 October 26, 2006http:// Monadic Programming October.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Higher-order Functions Dr. Hyunyoung Lee.
1 Haskell Kevin Atkinson John Simmons. 2 Contents Introduction Type System Variables Functions Module System I/O Conclusions.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Interactive Programs: I/O and Monads Dr. Hyunyoung Lee.
Java Classes Chapter 1. 2 Chapter Contents Objects and Classes Using Methods in a Java Class References and Aliases Arguments and Parameters Defining.
Scrap your boilerplate: generic programming in Haskell Ralf Lämmel, Vrije University Simon Peyton Jones, Microsoft Research.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
 2003 Prentice Hall, Inc. All rights reserved. 1 Chapter 3 - Functions Outline 3.15Functions with Empty Parameter Lists 3.16Inline Functions 3.17References.
0 PROGRAMMING IN HASKELL Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and a few other sources) Odds and Ends,
Constructors, Copy Constructors, constructor overloading, function overloading Lecture 04.
More Data Types CSCE 314 Spring CSCE 314 – Programming Studio Defining New Data Types Three ways to define types: 1.type – Define a synonym for.
Recursion Higher Order Functions CSCE 314 Spring 2016.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
Simon Peyton Jones, Stephanie Weirich, Richard Eisenberg, Dimitrios Vytiniotis Microsoft Research University of Pennsylvania April 2016.
0 PROGRAMMING IN HASKELL Typeclasses and higher order functions Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and.
Set Comprehensions In mathematics, the comprehension notation can be used to construct new sets from old sets. {x2 | x  {1...5}} The set {1,4,9,16,25}
Set Comprehensions In mathematics, the comprehension notation can be used to construct new sets from old sets. {x2 | x  {1...5}} The set {1,4,9,16,25}
String is a synonym for the type [Char].
Programming Languages
dr Robert Kowalczyk WMiI UŁ
Theory of Computation Lecture 4: Programs and Computable Functions II
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Introduction interface in Java is a blueprint of a class. It has static constants and abstract methods only. An interface is a way to describe what classes.
Microsoft Research University of Pennsylvania
Advanced Functional Programming
Types and Classes in Haskell
PROGRAMMING IN HASKELL
Higher Order Functions
PROGRAMMING IN HASKELL
Records and Type Classes
PROGRAMMING IN HASKELL
Programming Languages
PROGRAMMING IN HASKELL
Records and Type Classes
Presentation transcript:

Scrap Your Boilerplate /~simonpj/papers/hmap/

Outline Boilerplate code Boilerplate code Idea Idea Recursively apply Recursively apply Generic transform Generic transform “ Casting ” solution“ Casting ” solution AOP solutionAOP solution Visitor pattern Visitor pattern Queries and monadic transformations Queries and monadic transformations Boilerplate 2 & 3 Boilerplate 2 & 3

Boilerplate Code data Company= C [Dept] data Dept= D Name Manager [SubUnit] data SubUnit= PU Employee | DU Dept data Employee= E Person Salary data Person= P Name Address data Salary= S Float type Manager= Employee type Name= String type Address= String increase :: Float -> Company -> Company increase k (C ds) = C (map (incD k) ds) incD k (D nm mgr us) = D nm (incE k mgr) (map (incU k) us) incU k (PU e) = PU (incE k e) incU k (DU d) = DU (incD k d) incE k (E p s) = E p (incS k s) incS k (S s) = S (s * (1 + k)) Boilerplate

Idea Apply a generic transform Apply a generic transform Replacing incD, incU, incE and incSReplacing incD, incU, incE and incS Apply the transform Apply the transform RecursivelyRecursively BlindlyBlindly Only affect the items we want Only affect the items we want Increase k = everywhere $ mkT $ incS k Increase k = everywhere $ mkT $ incS k Generate a generic transform Recursively, blindly apply

Recursively apply One-layer traversal One-layer traversal class Typeable a => Term a where gmapT :: (forall b. Term b => b -> b) -> a -> a class Typeable a => Term a where gmapT :: (forall b. Term b => b -> b) -> a -> a instance Term Employee where gmapT f (E per sal) = E (f per) (f sal) instance Term Employee where gmapT f (E per sal) = E (f per) (f sal) instance Term Bool where gmapT f x = x instance Term Bool where gmapT f x = x instance Term a => Term [a] where gmapT f []= [] gmapT f (x:xs)= f x : f xs instance Term a => Term [a] where gmapT f []= [] gmapT f (x:xs)= f x : f xs

Recursively apply (cont.) everywhere :: Term a => (forall b. Term b => b -> b) -> a -> a everywhere :: Term a => (forall b. Term b => b -> b) -> a -> a everywhere f x = f $ gmapT (everywhere f) x everywhere f x = f $ gmapT (everywhere f) x everywhere ’ f x = gmapT (everywhere ’ f) (f x) everywhere ’ f x = gmapT (everywhere ’ f) (f x)

Recursively apply (cont.) Every involved data type have to be an instance of Term Every involved data type have to be an instance of Term The instantiation can be generated automatically The instantiation can be generated automatically “ deriving ” in GHC 6.4“ deriving ” in GHC 6.4 Different combinations of gmapT lead to different traversal policy Different combinations of gmapT lead to different traversal policy Rank-2 types, signature always needed Rank-2 types, signature always needed

“Casting” Solution class Typeable class Typeable cast :: (Typeable a, Typeable b) => a -> Maybe b cast :: (Typeable a, Typeable b) => a -> Maybe b (cast ‘ a ’ ) :: Maybe Char(cast ‘ a ’ ) :: Maybe Char Just ‘ a ’ Just ‘ a ’ (cast ‘ a ’ ) :: Maybe Bool(cast ‘ a ’ ) :: Maybe Bool Nothing Nothing (cast True) :: Maybe Bool(cast True) :: Maybe Bool Just True Just True

“Casting” Solution (cont.) mkT: generate a generic transform mkT: generate a generic transform When the applied parameter is what we expect, apply the transformWhen the applied parameter is what we expect, apply the transform Otherwise, work like idOtherwise, work like id mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a mkT f = case cast f of Just g-> g Nothing-> id mkT f = case cast f of Just g-> g Nothing-> id

“Casting” Solution (cont.) Need a language supported “ cast ” Need a language supported “ cast ” GHC 6.4 internal/libraryGHC 6.4 internal/library Data.Typeable: Typeable, castData.Typeable: Typeable, cast Data.Generics.Basic: Data (Term)Data.Generics.Basic: Data (Term) Cannot write transformation directly, always generated by mkT Cannot write transformation directly, always generated by mkT

AOP Solution incS is itself the (dummy) generic transform incS is itself the (dummy) generic transform Decide whether the transform is applied or not by advice Decide whether the transform is applied or not by advice incS :: Float -> a -> a incS k = id incS :: Float -> a -> a incS k = id advice around {incS k} (arg::Salary) = case arg of (S x) -> (S x*(1+k)) advice around {incS k} (arg::Salary) = case arg of (S x) -> (S x*(1+k)) increase k = everywhere $ incS k increase k = everywhere $ incS k

AOP Solution (cont.) type Salary = Float type Salary = Float In “ casting ” solution, every field with type Float will be multiplied (including height, weight, etc.) In “ casting ” solution, every field with type Float will be multiplied (including height, weight, etc.) In AOP Solution (?): advice around {incS k} (arg::Salary) = arg * (1 + k) In AOP Solution (?): advice around {incS k} (arg::Salary) = arg * (1 + k)

AOP Solution (cont.) Less boilerplate code Less boilerplate code Less data type for distinguishing meaning of data Less data type for distinguishing meaning of data Dummy transformation, real work is done by advices Dummy transformation, real work is done by advices idT = id advice around {idT} (arg::Salary) = incS k arg increase = everywhere idTidT = id advice around {idT} (arg::Salary) = incS k arg increase = everywhere idT

Visitor pattern

Visitor pattern (cont.) Widely used in single-dispatch OO languages Widely used in single-dispatch OO languages Visited object do the recursion Visited object do the recursion Decide whether the transform is applied or not by dispatching Decide whether the transform is applied or not by dispatching

Queries and monadic transform class Typeable a => Term a where gmapT :: (forall b. Term b => b -> b) -> a -> a gmapQ :: (forall b. Term b=> b -> r) -> a -> [r] gmapM :: Monad m => (forall b. Term b -> m a) -> a -> m a -- special cases of gfoldl class Typeable a => Term a where gmapT :: (forall b. Term b => b -> b) -> a -> a gmapQ :: (forall b. Term b=> b -> r) -> a -> [r] gmapM :: Monad m => (forall b. Term b -> m a) -> a -> m a -- special cases of gfoldl everything :: Term a => (r -> r -> r) -> (forall a. Term a => a -> r) -> a -> r everything :: Term a => (r -> r -> r) -> (forall a. Term a => a -> r) -> a -> r everywhereM :: (b -> m b) -> a -> m a everywhereM :: (b -> m b) -> a -> m a

Queries and monadic transform (cont.) (r `mkQ` q) a = case cast a of Just b-> q b Nothing-> r (r `mkQ` q) a = case cast a of Just b-> q b Nothing-> r mkM f = case cast f of Just g-> g Nothing-> return mkM f = case cast f of Just g-> g Nothing-> return totalBill = everything (+) (0 `mkQ` billS) totalBill = everything (+) (0 `mkQ` billS) dbSalaries = everywhereM (mkM lookupE) dbSalaries = everywhereM (mkM lookupE)

Queries and monadic transform (cont.) queryS _ = 0 :: Float queryS _ = 0 :: Float advice around {queryS} (arg::Salary) = case arg of S s -> s advice around {queryS} (arg::Salary) = case arg of S s -> s totalBill = everything (+) queryS totalBill = everything (+) queryS transM _ = return transM _ = return advice around {transM} (arg::Employee) = case arg of E n _) _ -> do s do s <- dbLookup n; return $ E p s dbSalaries = everywhereM transM dbSalaries = everywhereM transM

Boilerplate 2 Reflection: Already in GHC 6.4 library Reflection: Already in GHC 6.4 library Generic map, zip Generic map, zip extQ, extT, extM extQ, extT, extM Extend a generic query/transformation/ monadic transformation by a type- specific caseExtend a generic query/transformation/ monadic transformation by a type- specific case GHC 6.4, Data.Generics.AliasGHC 6.4, Data.Generics.Alias

Boilerplate 3 Generalizing queries on Data (Term) Generalizing queries on Data (Term) gsize :: Data a => a -> Intgsize :: Data a => a -> Int gsize t = gsize_def `extQ` name_size `extQ` phone_sizegsize t = gsize_def `extQ` name_size `extQ` phone_size class Size a where gsize :: a -> Intclass Size a where gsize :: a -> Int instance Data t => Size t where gsize t = 1 + sum (gmapQ gsize t) instance Data t => Size t where gsize t = 1 + sum (gmapQ gsize t) class Size a => Data a where … class Size a => Data a where … This belongs to the SYB “ library ” Needed for “ every ” query

Boilerplate 3 (cont.) Need “ type variable over classes ” Need “ type variable over classes ” Can be encoded straightforwardly in standard HaskellCan be encoded straightforwardly in standard Haskell API of Data changed API of Data changed AOP solution cleaner AOP solution cleaner gsize t = 1 + sum (gmapQ gsize t)gsize t = 1 + sum (gmapQ gsize t) advice around {gsize} (arg::Name) = case arg of (N _) -> 1advice around {gsize} (arg::Name) = case arg of (N _) -> 1 advice around {gsize} (arg::PhoneNumber) = length arg -- another special caseadvice around {gsize} (arg::PhoneNumber) = length arg -- another special case