Software System Design and Implementation

Similar documents
Advanced Functional Programming

Handout 10: Imperative programs and the Lambda Calculus

CS 11 Haskell track: lecture 5. This week: State monads

Monads. COS 441 Slides 16

Monads. Functional Programming (CS4011) Monads

Programming Languages

10/21/08. Monads for functional programming uses! Kathleen Fisher!

I/O in Haskell. To output a character: putchar :: Char -> IO () e.g., putchar c. To output a string: putstr :: String -> IO () e.g.

Software System Design and Implementation

Functional Programming and Haskell

Haskell & functional programming, some slightly more advanced stuff. Matteo Pradella

CS The IO Monad. Slides from John Mitchell, K Fisher, and S. Peyton Jones

Programming in Haskell Aug Nov 2015

Haskell Monads CSC 131. Kim Bruce

Monad class. Example: Lambda laughter. The functional IO problem. EDAN40: Functional Programming Functors and Monads

Witnessing Purity, Constancy and Mutability APLAS Ben Lippmeier Australian National University 2009/12/14

A Pragmatic Case For. Static Typing

Advanced Programming Handout 7. Monads and Friends (SOE Chapter 18)

f() ! " Run a higher-priority task? ! " Yield the processor to another task because our ! " Use the processor for some other activity while

CS 410/510: Advanced Programming

CS457/557 Functional Languages

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Structural polymorphism in Generic Haskell

Principles of Programming Languages

Programming with Math and Logic

Applicative, traversable, foldable

Types and Type Inference

Monads and all that I. Monads. John Hughes Chalmers University/Quviq AB

Background Type Classes (1B) Young Won Lim 6/28/18

Type-indexed functions in Generic Haskell

Applicative, traversable, foldable

Explicit Recursion in Generic Haskell

Part 0. A (Not So) Brief Introduction to Haskell

JVM ByteCode Interpreter

IO Monad (3D) Young Won Lim 1/18/18

Standard prelude. Appendix A. A.1 Classes

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

FUNCTIONAL PEARL. Global variables in Haskell

Software System Design and Implementation

Introduction to Haskell

Towards Reasoning about State Transformer Monads in Agda. Master of Science Thesis in Computer Science: Algorithm, Language and Logic.

COMP3151/9151 Foundations of Concurrency Lecture 8

CSE 230. Concurrency: STM. Slides due to: Kathleen Fisher, Simon Peyton Jones, Satnam Singh, Don Stewart

CSCI-GA Scripting Languages

INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION. Instructors: James Jones Copyright Instructors.

Advances in Programming Languages

More on functional programming

Overloading, Type Classes, and Algebraic Datatypes

CSC324 Principles of Programming Languages

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

CSCE 314 Programming Languages Functors, Applicatives, and Monads

PARALLEL AND CONCURRENT PROGRAMMING IN HASKELL

Software System Design and Implementation

These notes are intended exclusively for the personal usage of the students of CS352 at Cal Poly Pomona. Any other usage is prohibited without

COMP 3141 Software System Design and Implementation

Principles of Programming Languages

CS 360: Programming Languages Lecture 12: More Haskell

References. Monadic I/O in Haskell. Digression, continued. Digression: Creating stand-alone Haskell Programs

The Haskell HOP: Higher-order Programming

CS 320: Concepts of Programming Languages

Part VI. Imperative Functional Programming

INTRODUCTION TO HASKELL

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Fundamental Concepts and Definitions

Types and Type Inference

Monads. Bonus lecture 2017 David Sands

CS 11 Haskell track: lecture 1

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Haskell 98 in short! CPSC 449 Principles of Programming Languages

EECS 700 Functional Programming

Applicatives Comparisons (2C) Young Won Lim 3/6/18

Contents. A Source Code 32 A.1 ASCII versions of mathematical symbols A.2 Definitions of used library functions... 32

Using Monads for Input and Output

CSCE 314 Programming Languages. Interactive Programming: I/O

IO Monad (3C) Young Won Lim 1/6/18

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

G Programming Languages - Fall 2012

Informatics 1 Functional Programming Lectures 15 and 16. IO and Monads. Don Sannella University of Edinburgh

College Functors, Applicatives

Monad Background (3A) Young Won Lim 10/5/17

Intermediate Code Generation

A Functional Specification of Effects

OCaml Language Choices CMSC 330: Organization of Programming Languages

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Composable Shared Memory Transactions Lecture 20-2

Trees. Solution: type TreeF a t = BinF t a t LeafF 1 point for the right kind; 1 point per constructor.

G Programming Languages - Fall 2012

Functional Logic Programming Language Curry

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Testing. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 2. [Faculty of Science Information and Computing Sciences]

CITS 3242 Programming Paradigms Part II. Topic 10: Imperative Programming

CS 11 Haskell track: lecture 4. n This week: Monads!

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Lazy Functional Programming in Haskell

Optimising Functional Programming Languages. Max Bolingbroke, Cambridge University CPRG Lectures 2010

Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell

To figure this out we need a more precise understanding of how ML works

Maybe Monad (3B) Young Won Lim 12/21/17

Transcription:

Software System Design and Implementation Controlling Effects Gabriele Keller The University of New South Wales School of Computer Science and Engineering Sydney, Australia COMP3141 18s1

Examples of effects printf ("Hello World!"); I/O effect char c = getchar (); I/O effect int *p; write effect... *p = *p + 2; read effect

class MyException extends Exception {}... throw new MyException(); exception effect (non-local control flow) pthread_t mythread; pthread_create (&mythread, NULL, thread_function, NULL); thread-creation effect

Internal versus external effects External effects can be observed outside of the function where they occur I/O is an external effect Accessing a global variable may be an external effect Internal effects cannot be observed on the outside Allocating, using, and deallocating memory We can often treat a function with only internal effects as a pure function Purity is about what is observable!

A definition of pure functions A pure function is fully specified by a mapping of argument to result values Consequences include the following: Two invocations with the same arguments result in the same result A pure function leaves no observable trace beyond its result Caveat: Purity pertains to a particular level of abstraction After all, the assembly instructions of a pure Haskell function are not pure

A definition of impure or effectful functions An impure or effectful function is one that is not pure: it makes use of information beyond its arguments or produces an observable effect beyond its result (or both) They are not functions in the mathematical sense; they are sometimes called procedures

Why are effects harmful? They introduce (often subtle) requirements on the execution order They are not readily apparent from a function prototype or signature They introduce non-local dependencies They interfere badly with strong typing; for example: Subtyping and mutable arrays in Java (even worse with generics) Polymorphism and mutable references in ML

Effects and execution order Execution order can be surprising Execution order can be indeterminate: getchar() example Global object initialisation Concurrency

Avoiding effects Without effects, all functions are pure Can you program like that? Experience suggest, yes actually, very well! Need to get used to the programming style, though It impacts the program structure (often positively) It may require the use of different algorithms Leads to purely functional programming

Sometimes we need effects Most notably: I/O is usually effectful Interoperating with impure languages requires effects Sometimes effectful algorithms are more efficient Internal effects are usually sufficient Haskell's approach: Pure by default, effectful when necessary!

Haskell functions are pure by default f :: a -> b Maps a value of type a to a value of type b without any effects Effectful functions require specialised types

Haskell functions are pure by default f :: a -> b Maps a value of type a to a value of type b without any effects Effectful functions require specialised types perform external effects and then return a value of type b g :: a -> IO b

Effects need to be carefully contained Effects have to be reflected in the type: g :: a -> World > (b, World) printstr :: String -> World > ((), World) getchar :: World > (Char, World) Why is this problematic?

Effects need to be carefully contained Effects have to be reflected in the type: g :: a -> World > (b, World) newtype IO b = IO (World -> (b, World)) conceptually, the World is hidden inside the abstract data type IO g :: a -> IO b main :: IO () getchar :: IO Char putstrln :: String -> IO ()

What can we do with IO operations? Combine them to form more complex IO-operations using the do notation: do { putstrln Hi, ; putstrln how are you? ; } :: IO() :: IO() Braces and semicolon optional This is a kind a function composition, as the world is passed from the first to the second operation, and so on All operations in the do have to be of type IO

The do notation and types getchar :: IO Char putchar :: Char -> IO () Type mismatch: IO Char!= Char putchar getchar Type error! Char do { c <- getchar; putchar c; } IO Char Strips the IO

What can we do with IO operations? do { ch1 <- getchar; ch2 <- getchar; if (ord ch1 < ord ch2) then putstrln yes else putstrln no } :: IO Char :: IO Char :: IO () :: IO ()

What can we do with IO operations? Call pure functions and bind their return value to a variable: do { ch <- getchar; let chup = toupper ch return (ord chup) } :: IO Char :: IO Char :: IO Int return :: a -> IO a

What can t we do with IO operations? We cannot write a function of type: IO a -> a

Effects need to be carefully contained f x =...g... contaminated by effects g :: a -> IO b g y =... If a pure function f calls an impure function g, f becomes impure We have the following rule: Only impure functions can call impure functions Haskell uses the type system, to enforce this rule Unless the inner function contains only internal effects that we encapsulate

Local state state can be different things Sometimes, local state is sufficient g :: a -> s > (b, s) State s b runstate :: State s a -> s -> (a, s) Let s say we want a global counter: type Counter = State Int getcnt :: Counter Int inccnt :: Counter () setcnt :: Int -> Counter () inccountermax :: Int -> Counter Bool inccountermax max = do curr <- getcnt if curr < max then do {inccnt; return False} else do {setcnt 0; return True}

Which on type constructors can we use the do notation? The type constructor m has to be a monad return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b called bind The do-notation is just syntactic sugar to make using bind more convenient Following properties have to be met: return a >>= k = k a ma >>= return = ma ma >>= (\x -> k x >>= h) = (ma >>= k) >>= h

Monads don t necessarily encapsulate state Maybe type constructor is another example of a monad data Maybe a = Nothing Just a return :: a -> Maybe a return x = Just x (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b (>>=) Nothing _ = Nothing (>>=) (Just x) f = f x

Monads don t necessarily encapsulate state [] type constructor is another example of a monad return :: a -> [a] return x = [x] (>>=) :: [a] -> (a -> [b]) -> [b] (>>=) as f = concat (map f as)

Generators in QuickCheck are monads searchtrees :: Gen BinaryIntTree searchtrees = sized searchtrees' where searchtrees' 0 = return Leaf searchtrees' n = do v <- (arbitrary :: Gen Int) fmap (insert v) (searchtrees' $ n - 1) fmap :: (a -> b) -> Gen a -> Gen b

The benefits of controlling effects Absence of effects makes strong typing in pure functions more powerful A type signature captures the entire interface of a function All dependencies are explicit in the form of data dependencies All dependencies are typed It is easier to reason about pure code & and it is easier to test pure code Testing and reasoning (formal & informal) is local, independent of context Type checking leads to stronger guarantees

The pure-by-default architecture Impure shell I/O Encapsulated internal state Pure application core

Mutable variables in Haskell

Mutable variables in IO computations data IORef a newioref :: a -> IO (IORef a) readioref :: IORef a -> IO a writeioref :: IORef a -> a -> IO () Let's look at an example

Two flavours of mutable variables data IORef a newioref :: a -> IO (IORef a) readioref :: IORef a -> IO a writeioref :: IORef a -> a -> IO () can only be run from main Let's look at an example data STRef s a newstref :: a -> ST s (STRef s a) readstref :: STRef s a -> ST s a writestref :: STRef s a -> a -> ST s () run with runst :: (forall s. ST s a) -> a

Encapsulated state Some algorithms suggest stateful code For example, a graph traversal marking visited nodes to spot cycles runst statefulgraphtraversal stateful inside pure from the outside The type variable s in STRef s a represents a state thread It ensures that state from one runst invocation cannot leak into another

IO versus ST data IORef a newioref :: a -> IO (IORef a) readioref :: IORef a -> IO a writeioref :: IORef a -> a -> IO () data STRef s a newstref :: a -> ST s (STRef s a) readstref :: STRef s a -> ST s a writestref :: STRef s a -> a -> ST s () Both IO and ST s mark the use of state Both can be used with the do notation