advanced functional programming tim sheard 1 lecture 17 advanced functional programming tim sheard...

33
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture: Staged computation •Difference between Haskell and ML •Intro to MetaML •Using staging to control evaluation order

Upload: ashley-fowler

Post on 17-Jan-2018

226 views

Category:

Documents


0 download

DESCRIPTION

Advanced Functional Programming Tim Sheard 3 Lecture 17 Differences (* Data definitions *) datatype 'a Tree = Tip of 'a | Fork of ('a Tree)*('a Tree) 'a = type variable constructors are not capitalized -- data definitions data Tree a = Tip a | Fork (Tree a) (Tree a) comments Type constructors are post fix constructor functions are always uncurried (use tuples) note use of "of"

TRANSCRIPT

Page 1: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 1Lecture 17

Advanced Functional Programming

Tim Sheard Oregon Graduate Institute of Science & Technology

Lecture: Staged computation •Difference between Haskell and ML•Intro to MetaML•Using staging to control evaluation order

Page 2: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 2Lecture 17

Differences in Types

type variables and type application'a Tree

type constructorsint, string, bool

tuples(int * string * int)

type variables and type applicationTree a

type constructorsInt, String, Bool

tuples(Int, String, Bool)

Page 3: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 3Lecture 17

Differences

(* Data definitions *)

datatype 'a Tree = Tip of 'a | Fork of ('a Tree)*('a Tree)

'a = type variableconstructors are not capitalized

-- data definitions

data Tree a = Tip a | Fork (Tree a) (Tree a)

comments

Type constructors are post fix

constructor functions are always uncurried (use tuples)

note use of "of"

Page 4: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 4Lecture 17

difference 2

(* function definitions *)

fun fact n = if n=0 then 1 else n * (fact (n-1));

fun depth (Tip a) = 0 | depth (Fork(x,y)) = 1 + max (depth x, depth y);

-- function definitions

fact n = if n==0 then 1 else n * (fact (n-1))

depth (Tip a) = 0depth (Fork x y) = 1 + max (depth x) (depth y)

note use of "fun"equality is double

=

use "bar" (|) to separate clauses

primitives more likely to be curried in

Haskell

Page 5: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 5Lecture 17

Data List a = [] | (:) a (list a)

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

pi = 3.14159

\ x -> x + 1

Datatype ‘a list = [] | (op ::) of ‘a * (‘a list)

fun map f [] = … | map f (x::xs) =

val pi = 3.14159

fn x => x + 1

Differences betwe

en Haske

ll & ML

Page 6: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 6Lecture 17

Some Primitives- op +;

val it = fn:int * int -> int- op *;val it = fn:int * int -> int- op -;val it = fn:int * int -> int

- op @;val it = fn:'a list * 'a list -> 'a list- length;val it = fn:'a list -> int- op ::;val it = fn:'a * 'a list -> 'a list- hd;val it = fn:'a list -> 'a- tl;val it = fn:'a list -> 'a list

Main> :t (+)(+) :: Num a => a -> a -> aMain> :t (*)(*) :: Num a => a -> a -> aMain> :t (-)(-) :: Num a => a -> a -> a

Main> :t (++)(++) :: [a] -> [a] -> [a]

Main> :t lengthlength :: [a] -> IntMain> :t (:)(:) :: a -> [a] -> [a]Main> :t headhead :: [a] -> aMain> :t tailtail :: [a] -> [a]

Page 7: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 7Lecture 17

Differences 3

(* variable definition *)

val tree1 = Fork(Fork(Tip 1,Tip 2), Tip 3);

-- variable definition

tree1 = Fork (Fork (Tip 1) (Tip 2)) (Tip 3)

use val to declare

variables

Page 8: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 8Lecture 17

functions

fn x => x + 1

let fun f x = x + 1in f 7 end

has type in ML is :

datatype T = ...

datatype ('a,'b) T = ...= (in MetaML only) 'a ('b T)

\ x -> x + 1

let f x = x + 1in f 7

has type in Haskell is ::

data T = ...

data T b a = ...

Page 9: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 9Lecture 17

case expressions

case x of [] => 5| (x::xs) => len xs + m3

case x of [] -> 5 (x:xs) -> len xs + m3

Page 10: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 10Lecture 17

Differences 4

(* booleans *)

- true;val it = true : bool- false;val it = false : bool

(* mutual recursion *)

fun even 0 = true | even n = odd (n-1)and odd 0 = false | odd n = even (n-1);

-- booleans

Main> :t TrueTrue :: BoolMain> :t FalseFalse :: Bool

-- mutual recursion

even 0 = Trueeven n = odd (n-1)odd 0 = Falseodd n = even (n-1)

No capitals

use of "and" must separate mutually recursive

functions

all functions are implicitly mutually recursive

Page 11: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 11Lecture 17

Intro to MetaML

Page 12: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 12Lecture 17

Controlling Evaluation Order

We want more than just the correct result!

We want to control other resources such as time and space without resorting to tricks or unnatural programming styles.

Mechanism - Control Evaluation Order

Page 13: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 13Lecture 17

Traditiona

l Approaches

Fixed evaluation order with language extensions

Lazy - Outermostadd strictness annotations

Strict - Innermostadd annotations like force and delay

Encode laziness using lambda in a strict settingdatatype 'a lazylist = lazyNil | lazyCons of 'a * (unit -> 'a lazylist);

fun count n = lazyCons(n, fn () => count (n+1))

Page 14: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 14Lecture 17

Limitations

None of these approaches allow computation under a lambda! This is sometimes just what is needed. For example:

fun power n = (fn x => if n=0 then 1 else x * (power (n-1) x))

power 2;

Page 15: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 15Lecture 17

Exampl

e reduction

(power 2) unfold the definition

(fn x => if 2=0 then 1 else x * (power (2-1) x)) perform the if, under the lambda

(fn x => x * (power (2-1) x)) unfold power again

(fn x => x * ((fn x => if 1=0 then 1 else x * (power (1-1) x)) x))use the beta rule to apply the explicit lambda to x

Page 16: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 16Lecture 17

Exampl

e (cont.

)(fn x => x * (if 1=0 then 1 else x * (power (1-1) x))) perform the if

(fn x => x * (x * (power (1-1) x))) unfold power again

(fn x => x * (x * ((fn x => if 0=0 then 1 else x * (power (0-1) x))) x)) use the beta rule to apply the explicit lambda to x

(fn x => x * (x * (if 0=0 then 1 else x * (power (0-1) x)))) perform the if

(fn x => x * (x * 1))

Page 17: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 17Lecture 17

Solution - Use richer

annotations

Brackets: < e >no reductions allowed in edelay computationif e:t then <e> : <t> (pronounced code of t)

Escape: ~ erelax the no reduction rule of brackets aboveEscape may only occur inside Bracketssplice code together to build larger code

Run: run eremove outermost bracketsforce computations which have been delayed

Page 18: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 18Lecture 17

Calculus

A calculus describes equivalences between program fragments.

The rules of a calculus can be applied in any order.

An implementation applies the rules in some fixed order.

Traditional rulesbeta – (fn x => e) v e[v/x]if – if true then x else y x – if false then x else y ydelta – 5 + 2 7

Page 19: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 19Lecture 17

Rules for code

Introduction rule for code< e >

1st elimination rule for code (escape-bracket elim)< … ~<e> … > ---> < … e … >~<e> must appear inside enclosing bracketse must be escape free<e> must be at level 0

2nd elimination rule for code (run-bracket elim)run <e> ---> eprovided e has no escapesthe whole expression is at level 0

Page 20: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 20Lecture 17

Power exampl

e revisited

(* power : int -> <int> -> <int> *)fun power n = fn x => if n=0 then <1> else < ~x * ~(power (n-1) x) >

(* ans : < int -> int > *)val ans = < fn z => ~(power 2 <z>) >;

Page 21: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 21Lecture 17

<fn z => ~ (power 2 <z>) >

<fn z => ~(if 2=0

then <1>

else < ~<z> * ~(power (2-1) <z>) >)>

<fn z => ~< ~<z> * ~(power (2-1) <z>) >>)

<fn z => ~< z * ~(power (2-1) <z>) >>)

<fn z => ~< z * ~(if 1=0 then <1> else < ~<z> * ~(power (1-1) <z>) >) >>)

Page 22: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 22Lecture 17

<fn z => ~< z * ~< ~<z> * ~(power (1-1) <z>) >>>

<fn z => ~< z * ~< z * ~(power (1-1) <z>) >>>

<fn z => ~< z * ~< z * ~(power 0 <z>) >>>

<fn z => ~< z * ~< z * ~<1> >>>

<fn z => ~< z * ~< z * 1 >>>

<fn z => ~< z * z * 1 >>

<fn z => z * z * 1>

Page 23: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 23Lecture 17

MetaML:

Meta-

programming

Meta-Programming: Programs that write programs

What Infrastructure is possible in a language designed to help support the algorithmic construction of other programs?Advantages of meta-programs

capture knowledgeefficient solutionsdesign ideas can be communicated and shared

Page 24: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 24Lecture 17

Types of meta-programs

Static generatorsGenerate code which is then “written to disk” and processed by normal compilers etc.Two kinds

Homogeneous systemsobject language = meta-

languageHeterogeneous systems

object-language different from meta-language

Run-time generatorsStaged ProgramsPrograms that generate other programs, and then execute the programs they generatedMetaML is a staged programming language which does run-time code generation

Page 25: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 25Lecture 17

MetaML & the Mustang Project

TheorySemantics of staged programs

What does it mean to have a staged program?How can we tell if a staged program computes the same result as its unstaged counterpart?Calculus of programs - Rules for reasoning

Staged type systemsA static type system keeps bad programs from executing by throwing away bad programs by refusing to compile them.A staged program admits more bad things.

E.g. using a variable before it is defined, or executing a program before its complete, for example.Staged languages need richer type systems to throw away these bad programs.

Automatic stagingpartial evaluation

Page 26: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 26Lecture 17

MetaML & the Mustang Project

ToolsStaged Languages

MetaML reflective: obj-lang = meta-lang = ML multi-stage

Heterogeneous (meta-lang=ML, obj-lang varies, 2 stage)

Page 27: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 27Lecture 17

Building

pieces of

code

-| <23>;val it = <23> : <int>

-| <length [1,2,3]>;val it = <%length [1,2,3]> :<int>

-| <23 + 5>;val it = <23 %+ 5> : <int>

-| <fn x => x + 5>;val it = <(fn a => a %+ 5)> : <int -> int>

-| <fn x => <x + 1>>;val it = <(fn a => <a %+ 1>)> : <int -> <int>>

Page 28: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 28Lecture 17

Let’s try it !

Run MetaML

Page 29: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 29Lecture 17

Composing pieces of

code

-| val x = <2>;val x = <2> : <int>

-| val y = <44 + ~x>;val y = <44 %+ 2> : <int>

-| fun pair x = <( ~x, ~x )>;val pair = Fn : ['b].<'b > -> <('b * 'b )>

-| pair <11>;val it = <(11,11)> : <(int * int)>

Page 30: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 30Lecture 17

Executing constructed code

-| val x = <34 + 2>;val x = <34 %+ 2> : ['a].<int>

-| run x;val it = 36 : int

-| fun id x = x;val id = Fn : ['a].'a -> 'a

-| val q = <1 + ~(id <2+3>) >;val q = <1 %+ 2 %+ 3> : <int>

-| run q;val it = 6 : int

Page 31: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 31Lecture 17

Multi-stage code

-| val z = <fn n => <n + 1>>;val z = <(fn a => <a %+ 1>)> : <int -> <int>>

-| val f = run z;val f = Fn : int -> <int>

-| f 12;val it = <%n %+ 1> : <int>

-| run it;val it = 13 : int

Page 32: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 32Lecture 17

The lift operator-| <4+1>;val it = <4 %+ 1> : <int>-| lift (4+1);val it = <5> : <int>

-| val z = <fn n => < ~(lift n) + 1>>;val z = <(fn a => <~(lift a) %+ 1>)> :<int -> <int>>

-| run z;val it = Fn : int -> <int>

-| it 5;val it = <5 %+ 1>: <int>

-| run it;val it = 6 : int

Page 33: Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:

Advanced Functional Programming

Tim Sheard 33Lecture 17

Lift v.s. lexical capture

Lift cannot be used on functions-| lift id;Error: The term: id Non Qualified type, not liftable: ? -> ?

Lift makes code readable-| fun f x = <(x, ~(lift x))>;val f = Fn : ['b^].'b -> <('b * 'b )>-| f 3;val it = <(%x,3)> : <(int * int)>

Lexical capture is more efficient-| lift [1+3,4,8-4];val it = <4 :: (4 :: (4 :: [])))> : <int list >