Type-driven Development of Communicating Systems in Idris › talks › idris-conc.pdf ·...
Transcript of Type-driven Development of Communicating Systems in Idris › talks › idris-conc.pdf ·...
Type-driven Development of CommunicatingSystems in Idris
Edwin Brady ([email protected])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)
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