first order haskell

15
First Order Haskell Neil Mitchell York University www.cs.york.ac.uk/ ~ndm λ

Upload: honorato-andrews

Post on 31-Dec-2015

26 views

Category:

Documents


0 download

DESCRIPTION

First Order Haskell. Neil Mitchell York University www.cs.york.ac.uk/~ndm. λ. First order vs Higher order. Higher order: functions are values Can be passed around Stored in data structure Harder for reasoning and analysis More syntactic forms Extra work for the analysis - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: First Order Haskell

First Order Haskell

Neil Mitchell

York University

www.cs.york.ac.uk/~ndmλ

Page 2: First Order Haskell

First order vs Higher order

Higher order: functions are values– Can be passed around– Stored in data structure

Harder for reasoning and analysis– More syntactic forms– Extra work for the analysis

Can we convert automatically?– Yes (that’s this talk!)

Page 3: First Order Haskell

Which are higher order?

[not x | x ← xs]let xs = x:xs in xs

putChar ‘a’

1

\x → not x

not . odd

not $ odd x

map not xs

foldl (+) 0 xs

a < b (+1)

const ‘N’

Page 4: First Order Haskell

Higher order features

Type classes are implemented as dictionaries– (==) :: Eq a a → a → Bool– (==) :: (a→a→Bool, a→a→Bool) → a → a → Bool

Monads are higher order– (>>=) :: Monad m m a → (a → m b) → m b

IO is higher order– newtype IO a = IO (World → (World, a))

Page 5: First Order Haskell

A map example

map f [] = []

map f (x:xs) = f x : map f xs

heads xs = map head xs

head is passed higher order map takes a higher order argument heads could be first order

Page 6: First Order Haskell

Reynold’s Style Defunctionalisation

data Func = Head

apply Head x = head x

map f [] = []

map f (x:xs) = apply f x : map f xs

heads xs = map Head xs

Move functions to data

John C. Reynolds, Definitional Interpreters for Higher-Order Programming Languages

Page 7: First Order Haskell

Reynold’s Style Defunctionalisation

Good– Complete, works on all programs– Easy to implement

Bad– No longer Hindley-Milner type correct– Makes the code more complex– Adds a level of indirection– Makes program analysis harder

Page 8: First Order Haskell

Specialisation

map_head [] = []

map_head (x:xs) = head x : map_head xs

heads xs = map_head xs

Move functions to code

Page 9: First Order Haskell

Specialisation

Find: map head xs– A call to a function (i.e. map)– With an argument which is higher order (i.e. head)

Generate: map_head xs = …– A new version of the function– With the higher order element frozen in

Replace: map_head xs– Use the specialised version

Page 10: First Order Haskell

Specialisation fails

(.) f g x = f (g x)

even = (.) not odd

check x = even x

Nothing available to specialise! Can be solved by a simple inline

check x = (.) not odd x

Page 11: First Order Haskell

An algorithm

1. Specialise as long as possible

2. Inline once

3. Goto 1

Stop when no higher order functions remain

Page 12: First Order Haskell

Algorithm fails

data Wrap a = Wrap (Wrap a) | Value a

f x = f (Wrap x)

check = f (Value head)

In practice, this is rare – requires a function to be stored in a recursive data structure and …

Detect, and revert to Reynold’s method

Page 13: First Order Haskell

Code Size

Specialisation approach reduces code volume– Average about 55% smaller code (20%-95% range)

Mark Jones, Dictionary-free Overloading by Partial Evaluation

0

500

1000

1500

2000

2500

3000

Nofib Programs (Imaginary)

Lin

es o

f C

od

e Higher order

First order

Page 14: First Order Haskell

Current uses

Performance optimiser– The first step, makes the remaining analysis simpler– Already increases the performance

Analysis tool– Catch, checking for pattern match safety– Keeps the analysis simpler

Implemented for Yhc (York Haskell Compiler)

Page 15: First Order Haskell

Conclusion

Higher order functions are good for programmers

Analysis and transformation are simpler in a first order language

Higher order functions can be removed Their removal can reduce code size