Top Banner
1 Generic programming — Or: write everything once RALF HINZE Institut f¨ ur Informatik, Lehrstuhl Softwaretechnik, Universit¨ at Freiburg Georges-K¨ ohler-Allee, Geb¨ aude 079, 79110 Freiburg i. Br. Email: [email protected] Homepage: http://www.informatik.uni-bonn.de/~ralf 4. Juli 2005 (Pick up the slides at .../~ralf/talks.html#T42.)
29

Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: [email protected] ... representation that can be

Aug 17, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

1 JJ J I II 2

Generic programming — Or: write everything once

RALF HINZE

Institut fur Informatik, Lehrstuhl Softwaretechnik, Universitat Freiburg

Georges-Kohler-Allee, Gebaude 079, 79110 Freiburg i. Br.

Email: [email protected]

Homepage: http://www.informatik.uni-bonn.de/~ralf

4. Juli 2005

(Pick up the slides at .../~ralf/talks.html#T42.)

Page 2: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

2 JJ J I II 2

Introduction

Motto:

Generic programming is about making programs more adaptable by makingthem more general.

Generic programming languages allow a wider range of entities as parameters thanis available in more traditional languages: generic programs possibly abstract over

I other programs,

I types or type constructors,

I modules,

I classes,

I . . .

Page 3: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

3 JJ J I II 2

Introduction — continued

In this talk, we look at a particularly elegant instantiation of the idea of genericprogramming: data-generic programming.

A data-generic program is a collection of functions and types that are definedby induction on the structure of types.

Benefits: a data-generic program

I automatically adapts to changes in the representation of data,

☞ partial answer to the problem of software evolution,

I is usually simpler and more concise than a specific instance.

Page 4: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

4 JJ J I II 2

Related work

The concept of data-generic programming trades under a variety of names:

I structural polymorphism,

I type parametric programming,

I shape polymorphism,

I intensional polymorphism,

I polytypic programming.

Related lines of research:

I Standard Template Library (STL): parametric (or bounded) polymorphism,

I meta-programming: programs that manipulate other programs,

I reflection: ability of a program to examine and modify its structure.

Page 5: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

5 JJ J I II 2

Overview

A brief look at Haskell:

✖ Data types

A generic programming extension for Haskell:

✖ Generic functions on types

✖ Generic functions on type constructors

✖ Generic types

✖ Projects

Page 6: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

6 JJ J I II 2

Data types

In Haskell, a new type is introduced via a data declaration.

Examples:

data Color = Red | Green | Blue

☞ Color is a type, Red , Green and Blue are data constructors.

data Maybe α = Nothing | Just α

data Tree α = Empty | Node (Tree α) α (Tree α)

☞ α is a type parameter, Maybe and Tree are type constructors (functions ontypes).

Page 7: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

7 JJ J I II 2

Data types — example: abstract syntax trees

data Expr = Var Var -- variable| Nil -- nil| Num Integer -- numeral| String String -- string literal| Call Ident [Expr ] -- function call| Un UnOp Expr -- unary operator| Bin Expr BinOp Expr -- binary operator| Record [(Ident ,Expr )] TyIdent -- record creation| Array TyIdent Expr Expr -- array creation| Block [Expr ] -- compound statement| Assign Var Expr -- assignment| IfThen Expr Expr -- one-sided alternative| IfElse Expr Expr Expr -- two-sided alternative| While Expr Expr -- while loop| For Ident Expr Expr Expr -- for loop| Let [Decl ] Expr -- local definitions| Break -- loop exit

Page 8: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

8 JJ J I II 2

Data types — example: nested types

Algebraic data types are surprisingly expressive: the following definition capturesthe structural invariants of 2-3 trees: all leaves occur at the same level.

data Node α = Node2 α α | Node3 α α α

data Tree23 α = Zero α | Succ (Tree23 (Node α))

☞ Tree23 is a so-called nested data type.

☞ OO: algebraic data types are closely related to the Composite pattern.

Page 9: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

9 JJ J I II 2

The structure of data types

What is the structure of algebraic data types?

Data types are built from primitive types (Integer , Char , etc) and threeelementary types: the one-element type, binary sums, and binary products (belowexpressed as data types),

data 1 = ()

data α× β = (α, β)

data α + β = Inl α | Inr β

using type abstraction, type application, and type recursion.

Page 10: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

10 JJ J I II 2

Overview

A brief look at Haskell:

✔ Data types

A generic programming extension for Haskell:

✖ Generic functions on types

✖ Generic functions on type constructors

✖ Generic types

✖ Projects

Page 11: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

11 JJ J I II 2

Generic functions on types

A generic function is defined by induction on the structure of types.

Example: lexicographic ordering of values.

data Ordering = LT | EQ | GT

compare :: (τ , τ ) → Ordering

☞ compare is not a parametrically polymorphic function: a polymorphicfunction happens to be insensitive to what type the values in some structure are;the action of a generic function depends on the type argument.

Page 12: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

12 JJ J I II 2

Generic functions — ordering

Implementing compare so that it works for arbitrary data types seems like a hardnut to crack. The good news is that it suffices to define compare for the threeelementary types (the one-element type, binary sums, and binary products).

compare〈α〉 :: (α, α) → Ordering

compare〈1〉 ((), ()) = EQ

compare〈α + β〉 (Inl a1, Inl a2) = compare〈α〉 (a1, a2)compare〈α + β〉 (Inl a1, Inr b2) = LTcompare〈α + β〉 (Inr b1, Inl a2) = GTcompare〈α + β〉 (Inr b1, Inr b2) = compare〈β〉 (b1, b2)

compare〈α× β〉 ((a1, b1), (a2, b2)) = case compare〈α〉 (a1, a2) ofLT → LTEQ → compare〈β〉 (b1, b2)GT → GT

☞ For emphasis, the type argument is enclosed in angle brackets.

Page 13: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

13 JJ J I II 2

Generic functions — examples

More examples:

I equality: deep equality,

I pretty printing: showing a value in a human-readable format,

I parsing: reading a value from a human-readable format,

I visualisation: converting a tree to a graphical representation,

I serialising (marshalling, pickling): conversion to an external datarepresentation that can be transmitted across a network,

I data compression: conversion to a format that takes less space,

I generic traversals,

I . . .

Page 14: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

14 JJ J I II 2

Overview

A brief look at Haskell:

✔ Data types

A generic programming extension for Haskell:

✔ Generic functions on types

✖ Generic functions on type constructors

✖ Generic types

✖ Projects

Page 15: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

15 JJ J I II 2

Generic functions on type constructors

The function compare abstracts over a type: it generalises functions of type

(Color ,Color ) → Ordering ,(List Char ,List Char ) → Ordering(Tree Integer ,Tree Integer ) → Ordering(List (Tree Integer ),List (Tree Integer )) → Ordering. . .

to a single generic function of type

compare〈α〉 :: (α, α) → Ordering

Page 16: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

16 JJ J I II 2

Generic functions — continued

A generic function may also abstract over a type constructor.

For instance, the function that counts the number of elements in a containergeneralises functions of type

∀α .List α → Integer∀α .Tree α → Integer∀α .List (Tree α) → Integer∀α .Tree23 α → Integer. . .

to a single generic function of type

size〈ϕ〉 :: ∀α . ϕ α → Integer

Page 17: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

17 JJ J I II 2

Generic functions — size

The definition of size proceeds in two steps:

count〈α〉 :: α → Integercount〈1〉 () = 0count〈α + β〉 (Inl a) = count〈α〉 acount〈α + β〉 (Inr b) = count〈β〉 bcount〈α× β〉 (a, b) = count〈α〉 a + count〈β〉 b

size〈ϕ〉 :: ∀α . ϕ α → Integersize〈ϕ〉 = count〈ϕ α〉 where count〈α〉 a = 1

Page 18: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

18 JJ J I II 2

Generic functions — examples

More examples:

I many list processing functions can be generalised to arbitrary data types:sum, product , and , or , forall , exists , . . .

I container conversion,

I reduction with a monoid: a reduction is a function that collapses a structureof type ϕ α into a single value of type α,

I mapping function: a mapping function takes a function and applies it to eachelement of a given container, leaving its structure intact,

I mapping functions with effects,

I . . .

☞ Reductions and mapping functions are related to the Visitor and Iteratorpattern.

Page 19: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

19 JJ J I II 2

Overview

A brief look at Haskell:

✔ Data types

A generic programming extension for Haskell:

✔ Generic functions on types

✔ Generic functions on type constructors

✖ Generic types

✖ Projects

Page 20: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

20 JJ J I II 2

Generic types

A generic data type is a type that is defined by induction on the structure of anargument data type.

Example: Digital search trees, also known as tries, employ the structure of searchkeys to organise information.

{ear ,earl ,east ,easy ,eye}

=⇒

e

a

r

l

s

t y

y

e

A trie can be seen as a composition of finite maps.

Page 21: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

21 JJ J I II 2

Generic types — tries

Digital search trees are based on the laws of exponentials.

1 →fin ν ∼= ν(κ1 + κ2) →fin ν ∼= (κ1 →fin ν)× (κ2 →fin ν)(κ1 × κ2)→fin ν ∼= κ1 →fin (κ2 →fin ν)

Using the laws of exponentials we can define a generic type of finite maps:Map〈K 〉 V represents K →fin V .

data Map〈1〉 ν = Maybe νdata Map〈α + β〉 ν = Map〈α〉 ν ×Map〈β〉 νdata Map〈α× β〉 ν = Map〈α〉 (Map〈β〉 ν)

☞ The two type arguments of Map play different roles: Map〈K〉 V is definedby induction on the structure of K, but is parametric in V .

Page 22: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

22 JJ J I II 2

Generic types — tries: lookup

A generic look-up function:

lookup〈κ〉 :: ∀ν . κ → Map〈κ〉 ν → Maybe νlookup〈1〉 () t = tlookup〈α + β〉 (Inl a) (ta, tb) = lookup〈α〉 a talookup〈α + β〉 (Inr b) (ta, tb) = lookup〈β〉 b tblookup〈α× β〉 (a, b) ta = case lookup〈α〉 a ta of

Nothing → NothingJust tb → lookup〈β〉 b tb

☞ Interesting instances: Map〈List Char〉 is the type of ‘conventional’ tries,Map〈List Bit〉 is the type of binary tries.

Page 23: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

23 JJ J I II 2

Generic data types — examples

More examples:

I Memo functions.

I Xcomprez: compression of XML documents that are structured accordingto a Document Type Definition (DTD).

compression ratio 40%–50% better than XMill,

300 lines of Generic Haskell versus 20.000 lines of C++ for XMill,

uses HaXML to translate DTDs into data types.

I Trees with a focus of interest (navigation trees, zipper, finger, pointerreversal): used in editors for structured documents, theorem provers.

I Labelled or decorated trees.

I Data parallel arrays: flattening transformation for nested data parallelism.

I . . .

Page 24: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

24 JJ J I II 2

Overview

A brief look at Haskell:

✔ Data types

A generic programming extension for Haskell:

✔ Generic functions on types

✔ Generic functions on type constructors

✔ Generic types

✖ Projects

Page 25: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

25 JJ J I II 2

Projects

Past: Generic Haskell (2000–2004, supported by: NWO).

I Generic Haskell is an extension of Haskell that supports the construction ofgeneric programs. The examples above are written in Generic Haskell.

I Generic Haskell is implemented as a preprocessor (≈ 24.000 LOC) thattranslates generic functions into Haskell.

I see www.generic-haskell.org.

Future: Eine generische funktionale Programmiersprache: Theorie, Sprachentwurf,Implementierung und Anwendung (Aug. 2005–Jul. 2007, supported by: DFG).

I Integration of the extension into a standard Haskell compiler.

I Applications:refactoring, automatic testing,XML tools, data conversion.

I Generic specifications and proofs.

Page 26: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

26 JJ J I II 2

Overview

A brief look at Haskell:

✔ Data types

A generic programming extension for Haskell:

✔ Generic functions on types

✔ Generic functions on type constructors

✔ Generic types

✔ Projects

Page 27: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

27 JJ J I II 2

Conclusion

I Generic functions and types are defined by induction on the structure of types.

☞ The examples above are executable.

I A generic definition can be specialised to an arbitrary data type.

☞ It automatically adapts to changes in the representation of data.

I The generic definitions are statically typed; static typing guarantees thatevery instance will be well-typed.

I Generic programming, albeit more abstract, is often simpler and more concisethan ordinary programming: we only have to provide instances for threesimple, non-recursive data types.

Page 28: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

28 JJ J I II 2

Literature

I Ralf Hinze. A new approach to generic functional programming. In ThomasW. Reps, editor, Proceedings of the 27th Annual ACM SIGPLAN-SIGACTSymposium on Principles of Programming Languages, Boston,Massachusetts, January 19–21, 2000, pp. 119–132.

I Ralf Hinze. Polytypic values possess polykinded types. Science of ComputerProgramming, MPC Special Issue, 42:129–159, 2002.

I Ralf Hinze and Johan Jeuring. Generic Haskell: Practice and Theory. InRoland Backhouse and Jeremy Gibbons, editors, Generic Programming:Advanced Lectures, pp.1–56. Lecture Notes in Computer Science 2793.Springer-Verlag, 2003.

I Ralf Hinze and Johan Jeuring. Generic Haskell: Applications. In RolandBackhouse and Jeremy Gibbons, editors, Generic Programming: AdvancedLectures, pp.57–97. Lecture Notes in Computer Science 2793.Springer-Verlag, 2003.

I Ralf Hinze, Johan Jeuring, and Andres Loh. Type-indexed data types.Science of Computer Programmming, MPC Special Issue, 51:117–151, 2004.

Page 29: Generic programming — Or: write everything once · Georges-K¨ohler-Allee, Geb¨aude 079, 79110 Freiburg i. Br. Email: ralf@informatik.uni-bonn.de ... representation that can be

29 JJ J I II 2

Nested 2-3 trees explainedThe data constructors Zero and Succ have types:

Zero :: ∀α . α → Tree23 α

Succ :: ∀α .Tree23 (Node α) → Tree23 α

☞ Read the types as a term rewriting system.

Bottom-up construction of a 2-3 tree of height 2.

N2 (N2 1 2) (N2 2 3) :: Node (Node Int)Zero (N2 (N2 1 2) (N2 2 3)) :: Tree23 (Node (Node Int))

Succ (Zero (N2 (N2 1 2) (N2 2 3))) :: Tree23 (Node Int)Succ (Succ (Zero (N2 (N2 1 2) (N2 2 3)))) :: Tree23 Int

☞ The type in the first line mirrors the structure of the tree on the type level.