0% found this document useful (0 votes)
44 views75 pages

Generic Programming With Dependent Types: I

This document discusses generic programming in the Agda programming language. It introduces dependent types and how they enable generic programming. It gives examples of generalizing programs to be parametrically and ad hoc polymorphic. The document aims to introduce generic programming concepts in Agda.

Uploaded by

scvalencia606
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views75 pages

Generic Programming With Dependent Types: I

This document discusses generic programming in the Agda programming language. It introduces dependent types and how they enable generic programming. It gives examples of generalizing programs to be parametrically and ad hoc polymorphic. The document aims to introduce generic programming concepts in Agda.

Uploaded by

scvalencia606
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 75

Generic Programming With Dependent Types: I

Generic Programming in Agda

Stephanie Weirich

University of Pennsylvania
March 2426, 2010  SSGIP

Why study generic programming in dependently-typed


languages?

Why study generic programming in dependently-typed


languages?

Dependently-typed languages are current research topic and


likely component of next-generation languages.

Why study generic programming in dependently-typed


languages?

Dependently-typed languages are current research topic and


likely component of next-generation languages.

Generic programming is a

killer-app

for dependently-typed

languages. It is a source of programs that are dicult to type


check in other contexts.

Why study generic programming in dependently-typed


languages?

Dependently-typed languages are current research topic and


likely component of next-generation languages.

Generic programming is a

killer-app

for dependently-typed

languages. It is a source of programs that are dicult to type


check in other contexts.
3

TAKEAWAY: Dependent types are not just about program


verication, they really do add to expressiveness.

Spring School Goals and Non-Goals

Goals:

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers (I'm not)

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers (I'm not)

I'm ignoring termination

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers (I'm not)

I'm ignoring termination (with ags to Agda)

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers (I'm not)

I'm ignoring termination (with ags to Agda)

No interactive labs, sorry

Spring School Goals and Non-Goals

Goals:
1

Introduction to Agda language and dependently-typed


programming

Extended examples of generic programming

Non-goals:
1

I won't argue that Agda is best tool for generic programming


(it's not)

You won't be expert Agda programmers (I'm not)

I'm ignoring termination (with ags to Agda)

No interactive labs, sorry (try it at home!)

Where to go for more information

http://wiki.portal.chalmers.se/agda/

Agda Wiki

Stephanie Weirich and Chris Casinghino. Arity-generic

ACM SIGPLAN Workshop on


Programming Languages Meets Program Verication (PLPV),

type-generic programming. In
pages 1526, January 2010
3

References in the slides

All of the code from these slides, from my website

http://www.seas.upenn.edu/~sweirich/ssgip/

What is Agda?

Agda has a dual identity:


1

A functional programming language with dependent types


based on Martin-Lf intuitionistic type theory

A proof assistant, based on the Curry-Howard isomorphism

Historically derived from series of proof assistants and languages


implemented at Chalmers. Current version (ocially named Agda
2) implemented by Ulf Norell.

See Ulf Norell. Towards a practical programming language based on


dependent type theory. PhD thesis, Department of Computer Science and

Engineering, Chalmers University of Technology, SE-412 96 Gteborg, Sweden,


September 2007.

What is Agda?

Agda has a dual identity:


1

A functional programming language with dependent types


based on Martin-Lf intuitionistic type theory

A proof assistant, based on the Curry-Howard isomorphism

Historically derived from series of proof assistants and languages


implemented at Chalmers. Current version (ocially named Agda
2) implemented by Ulf Norell.

We will focus exclusively on the rst aspect.

See Ulf Norell. Towards a practical programming language based on


dependent type theory. PhD thesis, Department of Computer Science and

Engineering, Chalmers University of Technology, SE-412 96 Gteborg, Sweden,


September 2007.

Agda looks a bit like Haskell


Dene datatypes

data Bool :
true
false

:
:

Set

Bool
Bool

where

Agda looks a bit like Haskell


Dene datatypes

data Bool :
true
false

:
:

Set

where

Bool
Bool

Dene (inx) functions by pattern matching


__
true

Bool Bool
= true
= false

Bool

true

Agda looks a bit like Haskell


Dene datatypes

data Bool :
true
false

:
:

Set

where

Bool
Bool

Dene (inx) functions by pattern matching


__
true

Bool Bool
= true
= false

Bool

true

Dene mixx/polymorphic functions

: { A } Bool A A A
if true then e1 else e2 = e1
if false then e1 else e2 = e2

if_then_else

Inductive datatypes
Datatypes can be inductive

data N :
zero
suc

Set

where

: N
: NN

Inductive datatypes
Datatypes can be inductive

data N :
zero
suc

Set

where

: N
: NN

... and used to dene total recursive functions

: { A } N A List A
replicate zero
x = []
replicate (suc n) x = (x :: replicate n x)

replicate

Inductive datatypes
Datatypes can be inductive

data N :
zero
suc

Set

where

: N
: NN

... and used to dene total recursive functions

: { A } N A List A
replicate zero
x = []
replicate (suc n) x = (x :: replicate n x)

replicate

... and used to state properties about those functions

: { A } (x :
length (replicate n x) n

replicate-spec

A)

(n : N)

Polymorphic Length-indexed Vectors

Lists that know their length

data Vec (A :
[]
_::_

Set) : N Set where


: Vec A zero
: { n } A Vec A n Vec A (suc n)

Polymorphic Length-indexed Vectors

Lists that know their length

data Vec (A :
[]
_::_

Set) : N Set where


: Vec A zero
: { n } A Vec A n Vec A (suc n)

Give informative types to functions

: { A } (n : N) A Vec A n
x = []
repeat (suc n) x = x :: repeat n x
repeat

repeat zero

Lengths eliminate bugs

List "zap"
_ _

: { A B } List (A B) List A List B


[]
[]
= []
(a :: As) (b :: Bs) = (a b :: As Bs)

= error

Lengths eliminate bugs

List "zap"
_ _

: { A B } List (A B) List A List B


[]
[]
= []
(a :: As) (b :: Bs) = (a b :: As Bs)

= error

Vec "zap"
: { A B n } Vec (A B) n Vec A n Vec B n
~ []
= []
(a :: As) ~ (b :: Bs) = (a b :: As ~ Bs)

_~_
[]

Generic programming in Agda

Main thesis:
Dependently typed languages are not just for eliminating bugs, they
enable Generic Programming

Generic programming in Agda

Main thesis:
Dependently typed languages are not just for eliminating bugs, they
enable Generic Programming
But what is generic programming?

Generic programming in Agda

Main thesis:
Dependently typed languages are not just for eliminating bugs, they
enable Generic Programming
But what is generic programming? Lots of dierent denitions, but
they all boil down to lifting data structures and algorithms from
concrete instances to general forms.

Generalizing programs

Specic cases
zerox
zerox f x
onex
onex f x
twox
twox f x

: (Bool Bool) Bool Bool


= x
: (Bool Bool) Bool Bool
= fx
: (Bool Bool) Bool Bool
= f (f x)

Generalizing programs

Specic cases
zerox
zerox f x
onex
onex f x
twox
twox f x

: (Bool Bool) Bool Bool


= x
: (Bool Bool) Bool Bool
= fx
: (Bool Bool) Bool Bool
= f (f x)

Add extra argument

Generic function
: N (Bool Bool) Bool Bool
f x = x
nx (suc n) f x = nx n f (f x)
nx

nx zero

Parametric polymorphism

Specic cases
app-nat
app-nat f x
app-bool
app-bool f x

: (N N) N N
= fx
: (Bool Bool) Bool Bool
= fx

Parametric polymorphism

Specic cases
app-nat
app-nat f x
app-bool
app-bool f x

: (N N) N N
= fx
: (Bool Bool) Bool Bool
= fx

New argument could be an implicit, parametric type

Generic function
app

: { A } (A A) A A
= fx

app f x

Ad hoc polymorphism

: N N Bool
zero
=
eq-nat (suc n) (suc m) =
eq-nat
=

eq-nat

eq-nat zero

eq-bool

eq-bool false
eq-bool

eq-nat n m
false

Bool Bool
false
= true
true
= true
= false

Bool

eq-bool true

true

Ad hoc polymorphism

: N N Bool
zero
=
eq-nat (suc n) (suc m) =
eq-nat
=

eq-nat

eq-nat zero

eq-bool

true
eq-nat n m
false

Bool Bool
false
= true
true
= true
= false

Bool

eq-bool false
eq-bool true
eq-bool

J_K : Bool Set


J b K = if b then N else Bool

: (b : Bool) J b K J b K Bool
eq-nat-bool true = eq-nat
eq-nat-bool false = eq-bool

eq-nat-bool

General idea: universes for generic programming


Start with a code for types:

data Type :
nat
bool
pair

:
:
:

Set

where

Type
Type
Type

Type Type

General idea: universes for generic programming


Start with a code for types:

data Type :
nat
bool
pair

:
:
:

Set

where

Type
Type
Type

Type Type

Dene an interpretation as an Agda type

J_K : Type Set


J nat K
= N
J bool K
= Bool
J pair t1 t2 K = J t1 K J t2 K

General idea: universes for generic programming


Start with a code for types:

data Type :
nat
bool
pair

:
:
:

Set

where

Type
Type
Type

Type Type

Dene an interpretation as an Agda type

J_K : Type Set


J nat K
= N
J bool K
= Bool
J pair t1 t2 K = J t1 K J t2 K

Then dene generic function, dispatching on code


eq

: (t :

eq nat
eq bool
eq

(pair t1

J t K J t K Bool
y
= eq-nat x y
x
y
= eq-bool x y
t2 ) (x1 ,x2 ) (y1 ,y2 ) = eq t1 x1 y1 eq t2

Type)
x

x2 y2

Expressiveness
Patterns in both types and denitions

: {A B} B A B
zeroApp f x = f

zeroApp

oneApp

: { A B } (A B) A B
= fx

oneApp f x
twoApp

: { A B } (A A B) A B
= fxx

twoApp f x

Expressiveness
Patterns in both types and denitions

: {A B} B A B
zeroApp f x = f

zeroApp

oneApp

: { A B } (A B) A B
= fx

oneApp f x
twoApp

: { A B } (A A B) A B
= fxx

twoApp f x

: N Set Set Set


A B = B
NAPP (suc n) A B = A NAPP n A B
NAPP

NAPP zero

: { A B } (n : N) NAPP n A B A B
f x = f
nApp (suc n) f x = nApp n (f x) x
nApp

nApp zero

Key features of advanced generic programming

Strong elimination
if b then

N else Bool

Static case analysis on data to produce a type

Key features of advanced generic programming

Strong elimination
if b then

N else Bool

Static case analysis on data to produce a type

Dependent pattern matching


: (b : Bool) if b then N else Bool
= 0
f false = false

f true

Dynamic case analysis on data renes types

Key features of advanced generic programming

Strong elimination
if b then

N else Bool

Static case analysis on data to produce a type

Dependent pattern matching


: (b : Bool) if b then N else Bool
= 0
f false = false

f true

Dynamic case analysis on data renes types

Overall
Uniform extension of the notion of programmability from run-time
to compile-time.

Proof checking vs. Programming

Two uses for Agda are in conict

Proof checking vs. Programming

Two uses for Agda are in conict


Under the Curry-Howard isomorphism, only terminating
programs are proofs.

Proof checking vs. Programming

Two uses for Agda are in conict


Under the Curry-Howard isomorphism, only terminating
programs are proofs. An innite loop has any type, so can
prove any property
anything
anything

: {A} A
= anything

Proof checking vs. Programming

Two uses for Agda are in conict


Under the Curry-Howard isomorphism, only terminating
programs are proofs. An innite loop has any type, so can
prove any property
anything
anything

: {A} A
= anything

By default, Agda only accepts programs that it can show


terminate.

Proof checking vs. Programming

To prove that all programs terminate, Agda makes strong


restrictions on denitions
1

Predicative polymorphism

Structural recursive functions

Strictly-positive datatypes

Restrictions hinder

compile-time programmability.

Proof checking vs. Programming

To prove that all programs terminate, Agda makes strong


restrictions on denitions
1

Predicative polymorphism

Structural recursive functions

Strictly-positive datatypes

Restrictions hinder

compile-time programmability.

So, we remove them with ags

Proof checking vs. Programming

To prove that all programs terminate, Agda makes strong


restrictions on denitions

-type-in-type

Predicative polymorphism

Structural recursive functions

Strictly-positive datatypes

Restrictions hinder

compile-time programmability.

So, we remove them with ags

Proof checking vs. Programming

To prove that all programs terminate, Agda makes strong


restrictions on denitions

-type-in-type
functions -no-termination-check

Predicative polymorphism

Structural recursive

Strictly-positive datatypes

Restrictions hinder

compile-time programmability.

So, we remove them with ags

Proof checking vs. Programming

To prove that all programs terminate, Agda makes strong


restrictions on denitions
1
2
3

-type-in-type
Structural recursive functions -no-termination-check
Strictly-positive datatypes -no-positivity-check
Predicative polymorphism

Restrictions hinder

compile-time programmability.

So, we remove them with ags

Types are rst-class data


They may be:

Types are rst-class data


They may be:
Passed to functions, dependently or non-dependently

Set
f x = (x x)
g : (A : Set) A A
g A x = x
f

Set

Types are rst-class data


They may be:
Passed to functions, dependently or non-dependently

Set
f x = (x x)
g : (A : Set) A A
g A x = x
f

Set

Returned as results, dependently or non-dependently


h

h x

( A A)
= if x then (N,0) else (Bool,true)

Bool

Types are rst-class data


They may be:
Passed to functions, dependently or non-dependently

Set
f x = (x x)
g : (A : Set) A A
g A x = x
f

Set

Returned as results, dependently or non-dependently


h

h x

( A A)
= if x then (N,0) else (Bool,true)

Bool

Stored in data structures

(N :: Bool :: Vec N 3 :: []) :

List Set

Type in Type

Both types and regular data may be inferred by the type checker
(as implicit arguments) and symbolically evaluated at compile time.

Type in Type

Both types and regular data may be inferred by the type checker
(as implicit arguments) and symbolically evaluated at compile time.

What is the dierence between types and other sorts of data?

Type in Type

Both types and regular data may be inferred by the type checker
(as implicit arguments) and symbolically evaluated at compile time.

What is the dierence between types and other sorts of data?


Types can be used to classify data.

Type in Type

Both types and regular data may be inferred by the type checker
(as implicit arguments) and symbolically evaluated at compile time.

What is the dierence between types and other sorts of data?


Types can be used to classify data.
Types are classied by Set

Type in Type

Both types and regular data may be inferred by the type checker
(as implicit arguments) and symbolically evaluated at compile time.

What is the dierence between types and other sorts of data?


Types can be used to classify data.
Types are classied by Set
i.e. if

`e :

t then

`t :

Set and t is a type.

Type in Type

What about Set? What is its type?

Type in Type

What about Set? What is its type?


Flag

-type-in-type

enables

` Set :

Set

Type in Type

What about Set? What is its type?


Flag

-type-in-type

enables

` Set :

Set

Convenient for polymorphic data structures:

: { A n } Vec A (suc n) A
head (x :: xs) = x

head

Type in Type

What about Set? What is its type?


Flag

-type-in-type

enables

` Set :

Set

Convenient for polymorphic data structures:

: { A n } Vec A (suc n) A
head (x :: xs) = x

head

x
x

: Set
= head (N :: Bool :: [])

What about termination?

Type soundness is independent of termination. So even if we don't


know that programs terminate, we still know that they will not
crash.

What about termination?

Type soundness is independent of termination. So even if we don't


know that programs terminate, we still know that they will not
crash.
Knowing that we don't need an additional case in head is
independent of termination.

: { A n } Vec A (suc n) A
head (x :: xs) = x

head

What about termination?

Type soundness is independent of termination. So even if we don't


know that programs terminate, we still know that they will not
crash.
Knowing that we don't need an additional case in head is
independent of termination.

: { A n } Vec A (suc n) A
head (x :: xs) = x

head

Have

partial correctness:

the program is correct up to termination.

Caveats:
Invalid proofs can also cause programs to diverge. (And can't
erase them either!)
Implications are not to be trusted.

Coming next...

Two intensive examples of generic programming in Agda...

Coming next...

Two intensive examples of generic programming in Agda...


1

Kind-indexed type-directed programming

Coming next...

Two intensive examples of generic programming in Agda...


1

Kind-indexed type-directed programming

Arity-generic programming

You might also like