Type-driven Development of Communicating Systems in Idris › talks › idris-conc.pdf ·...

Post on 03-Jul-2020

5 views 0 download

Transcript of Type-driven Development of Communicating Systems in Idris › talks › idris-conc.pdf ·...

Type-driven Development of CommunicatingSystems in Idris

Edwin Brady (ecb10@st-andrews.ac.uk)University of St Andrews, Scotland, UK

@edwinbrady

Lambda World, October 1st 2016

Idris is a pure functional language with dependent types:

Encourages Type-driven Development

Totality checking

In this talk:

Total Functional Programming

Termination and Productivity

Total Functional Programming and Interaction

A practical example: Type Safe Concurrency

What is Type-driven Development?

Types as a plan for a program

Write types first

Define programs interactively

Programs may contain holesType checker directs programmer

Refine type and program as necessary

Process: Type, Define, Refine

What is Type-driven Development?

Types as a plan for a program

Write types first

Define programs interactively

Programs may contain holesType checker directs programmer

Refine type and program as necessary

Process: Type, Define, Refine

What is Type-driven Development?

Types as a plan for a program

Write types first

Define programs interactively

Programs may contain holesType checker directs programmer

Refine type and program as necessary

Process: Type, Define, Refine

What is Type-driven Development?

Types as a plan for a program

Write types first

Define programs interactively

Programs may contain holesType checker directs programmer

Refine type and program as necessary

Process: Type, Define, Refine

Type-driven Development

Type-driven Development

Type-driven Development

Total Functional Programming

A total function is a function which, for all well-typed inputs,either

Terminates with a well-typed result

Produces a finite prefix of a well-typed infinite result in finitetime

Why do we care?

If we care about types, we should care about totality

Given f : T

If f is total, we know that it will always give a result of type T

If f is partial, we know that if it gives a result, it will be oftype T

Examples: Vectors and Streams

Why do we care?

If we care about types, we should care about totality

Given f : Theorem

If f is total, we know that it will always give a result of typeTheorem

If f is partial, we know that if it gives a result, it will be oftype Theorem ???

Examples: Vectors and Streams

Totality Checking

Idris checks:

Coverage: patterns for all well-typed inputs

Termination: there is a decreasing argument

Productivity: recursive call is guarded by a constructor

Type-driven Development

Type-driven Development

(thanks to @aaronmblevin)

Commercial Break

https://www.tinyurl.com/typedd

Interactive Programs in Idris

Idris, like Haskell, uses IO for writing interactive programs

A value of type IO ty is a description of an interactive actionwhich results in a value of type ty

Example: Sequencing IO Actions

hello : IO ()

hello = do putStr "What is your name? "

name <- getLine

putStr ("Hello " ++ name)

Interactive Programs in Idris

Problem: we often want interactive programs to runindefinitely

Example: Looping IO Actions

loopy : IO ()

loopy = do putStr "What is your name? "

name <- getLine

putStr ("Hello " ++ name)

loopy -- Not total!

Composing actions in a recursive function may not be total

No structurally decreasing argument, in general

Interactive Total Functional Programs

Solution: Describe looping programs as a stream of IO actions:

data InfIO : Type where

Do : IO a -> (a -> Inf InfIO) -> InfIO

(>>=) : IO a -> (a -> Inf InfIO) -> InfIO

(>>=) = Do

Interactive Total Functional Programs

Then define a run function to execute those descriptions:

run : InfIO -> IO ()

Compare with IO:

IO ty is a description of actions which result in a ty

The run-time system executes those actions

run on InfIO does a similar job, at a different level

Interactive Total Functional Programs

Then define a run function to execute those descriptions:

run : InfIO -> IO ()

Compare with IO:

IO ty is a description of actions which result in a ty

The run-time system executes those actions

run on InfIO does a similar job, at a different level

Example: Concurrency

The Idris run-time system supports message passing concurrency

A process can spawn another process

A process can create a Channel, using:

connect, which initiates a connection to another processlisten, which waits for incoming connections

Processes can send and receive messages on a Channel

Message Passing Concurrency in Idris

Message Passing Concurrency in Idris

To write correct concurrent programs in this style, we’d like toensure, at least:

Requests (like Add 2 3) and Responses (like 5) are well-typedw.r.t. each other

Server processes (like Adder) run indefinitely

That is, they are productive

Server processes always complete responses to requests

That is, processing a response terminates

Server Processes

Types for Message Passing

We can achieve this with types:

Define a type for Requests

Define a function to calculate Response types from requests

This describes valid message types for interactions betweenprocesses

Define a type for servers, parameterised by the Request andResponse types it services

This defines the type of messages we can send to a processLike InfIO, a process is an infinite sequence of commandsLike InfIO, it guarantees productivityProcesses run indefinitely, and always complete requests

Types for Message Passing

We can achieve this with types:

Define a type for Requests

Define a function to calculate Response types from requests

This describes valid message types for interactions betweenprocesses

Define a type for servers, parameterised by the Request andResponse types it services

This defines the type of messages we can send to a processLike InfIO, a process is an infinite sequence of commandsLike InfIO, it guarantees productivityProcesses run indefinitely, and always complete requests

Types for Message Passing

Adder Requests/Responses

data Request = Add Nat Nat

Response : Request -> Type

Response (Add x y) = Nat

Adder Implementation

adder : ServerLoop Response ()

adder = do Accept (\msg =>

case msg of

Add x y => Pure (x + y))

Loop adder

Demonstration

Concurrent Processes in Action

Further Reading

On total functional programming:

David Turner, Elementary Strong Functional Programming,2005

On interactive programming with dependent types

Peter Hancock and Anton Setzer, Interactive Programs inDependent Type Theory, 2000

On types for communicating systems:

Kohei Honda, Types for Dyadic Interaction, 1993

Kohei Honda, Nobuko Yoshida, Marco Carbone, MultipartyAsynchronous Session Types, 2008

Philip Wadler, Propositions as Sessions, 2012

Summary

Total programs are either terminating or productive

Together, this allows us to write long running processes, whereevery request is processed in finite time

A useful pattern for concurrent programming is to:

Define server processes which respond to requestsWrite programs as a collection of client processes, makingremote procedure calls to servers

We can define long running, well typed, concurrent processesas potentially infinite streams of commands

Using dependent types (in particular, first class functions),we’ve described simple message passing protocols

https://www.tinyurl.com/typedd