10 21 08
play

10/21/08 cs242 Midterm: Wed. Oct. 22, 7-9pm, Gates B01 Closed - PDF document

10/21/08 cs242 Midterm: Wed. Oct. 22, 7-9pm, Gates B01 Closed book, but you may bring one, letter-sized page of notes, double sided. SCPD students: if you are local, please come to campus to take the exam. Kathleen


  1. 10/21/08
 cs242 �  Midterm: Wed. Oct. 22, 7-9pm, Gates B01 �  Closed book, but you may bring one, letter-sized page of notes, double sided. �  SCPD students: if you are local, please come to campus to take the exam. � Kathleen Fisher �  Homework assigned 10/15 will be ungraded, �  But we strongly urge you to do it! �  Solutions will be passed out on 10/20 � Reading: “Tackling the Awkward Squad,” Sections 1-2 � � “Real World Haskell,” Chapter 7: I/O �  Minor corrections to HW3 posted (#’ s 3 and 5). �  Reminder: you can work on homework in pairs. � Thanks to Simon Peyton Jones for many of these slides. � Functional programming is beautiful: �  Concise and powerful abstractions �  But to be useful as well as beautiful , a  higher-order functions, algebraic data types, language must manage the “Awkward Squad”: � parametric polymorphism, principled overloading, ... �  Input/Output �  Close correspondence with mathematics �  Imperative update �  Semantics of a code function is the math function �  Equational reasoning: if x = y, then f x = f y �  Error recovery (eg, timing out, catching divide by zero, etc.) �  Independence of order-of-evaluation (Church-Rosser) �  Foreign-language interfaces � e1 * e2 The compiler can  Concurrency � choose the best order in which to do e1’ * e2 e1 * e2’ evaluation, including The whole point of a running a program is to skipping a term if it affect the real world, an “update in place. ” � is not needed. � result  Do everything the “usual way”: � In a lazy functional language, like Haskell, the  I/O via “functions” with side effects: � order of evaluation is deliberately undefined , so putchar ‘x’ + putchar ‘y’ the “direct approach” will not work. �  Imperative operations via assignable reference cells: �  Consider: � res = putchar ‘x’ + putchar ‘y’ z = ref 0; z := !z + 1; f(z);  Output depends upon the evaluation order of ( + ). � w = !z (* What is the value of w? *)  Consider: � ls = [putchar ‘x’, putchar ‘y’]  Error recovery via exceptions �  Output depends on how the consumer uses the list.  Foreign language procedures mapped to “functions” � If only used in length ls , nothing will be printed  Concurrency via operating system threads � because length does not evaluate elements of list. �  Ok if evaluation order is baked into the language . � 1


  2. 10/21/08
  The reading uses a web server as an example. �  Laziness and side effects are incompatible. �  Lots of I/O, need for error recovery, need to  Side effects are important! � call external libraries, need for concurrency �  For a long time, this tension was embarrassing to the lazy functional programming community. � Client 1 � Client 2 � Client 3 � Client 4 �  In early 90’ s, a surprising solution (the monad) emerged from an unlikely source (category theory). � Web server �  Haskell’ s IO monad provides a way of tackling 1500 lines of Haskell � 700 connections/sec � the awkward squad: I/O, imperative state, exceptions, foreign functions, & concurrency. � Writing High-Performance Server Applications in Haskell by Simon Marlow � Monadic Input and Output � A functional The whole point of program defines a running a program Tension � pure function, with is to have no side effects. � some side effect. �  Streams �  Program issues a stream of requests to OS, which  Move side effects outside of functional program � responds with a stream of inputs. �  If Haskell main :: String -> String  Continuations �  User supplies continuations to I/O routines to specify Wrapper Program, written in some other language � how to process results. � standard standard  World-Passing � input output Haskell �  The “World” is passed around and updated, location location main like a normal data structure. � (file or (file or program �  Not a serious contender because designers didn’ t know stdin) � stdin) � how to guarantee single-threaded access to the world. �  Stream and Continuation models were discovered to be inter-definable. �  But what if you need to read more than one file? Or delete files? Or communicate over a socket? ... �  Haskell 1.0 Report adopted Stream model. � 2


  3. 10/21/08
  Move side effects outside of functional program �  Enrich argument and return type of main to include all input and output events. �  If Haskell main :: [Response] -> [Request] main :: [Response] -> [Request] data Request = ReadFile Filename | WriteFile FileName String | … data Response = RequestFailed Haskell � | ReadOK String program � | WriteOk [ Response ] [ Request ] | Success | …  Wrapper program interprets requests and  Laziness allows program to generate requests prior to adds responses to input. � processing any responses. �  Haskell 1.0 program asks user for filename, echoes name, reads file, and prints to standard out. �  Hard to extend: new I/O operations require adding new constructors to Request and main :: [Response] -> [Request] main ~(Success : ~((Str userInput) : ~(Success : ~(r4 : _)))) Response types and modifying the wrapper. � = [ AppendChan stdout "enter filename\n", ReadChan stdin,  No close connection between a Request and AppendChan stdout name, ReadFile name, corresponding Response , so easy to get “out- AppendChan stdout of-step,” which can lead to deadlock. � (case r4 of Str contents -> contents Failure ioerr -> "can’t open file")  The style is not composable: no easy way to ] where (name : _) = lines userInput combine two “main” programs. �  The ~ denotes a lazy pattern , which is evaluated  ... and other problems!!! only when the corresponding identifier is needed. � A value of type ( IO t ) is an “action. ” When A value of type ( IO t ) is an “action. ” When performed, it may do some input/output before performed, it may do some input/output before delivering a result of type t . � delivering a result of type t . � type IO t = World -> (t, World) result :: t IO t World in World out 3


  4. 10/21/08
 Char () A value of type ( IO t ) is an “action. ” When Char performed, it may do some input/output before delivering a result of type t . � getChar putChar type IO t = World -> (t, World)  “Actions” are sometimes called “computations. ” � getChar :: IO Char Main program is an action putChar :: Char -> IO () of type IO () �  An action is a first-class value. � main :: IO ()  Evaluating an action has no effect; main = putChar ‘x’ performing the action has the effect. � >>= >>= (>>=) :: IO a -> (a -> IO b) -> IO b To read a character and then write it back out, we need to connect two actions. � () () Char getChar putChar Char getChar putChar  We have connected two actions to make a new, bigger action. � echo :: IO () echo = getChar >>= putChar >>= >>=  Operator is called bind because it binds the result of the left-hand action in the action on echoDup :: IO () the right. � echoDup = getChar >>= (\c -> putChar c >>= (\() ->  Performing compound action a >>= \x->b: � putChar c ))  performs action a, to yield value r �  applies function \x->b to r �  performs the resulting action b{x <- r} �  The parentheses are optional because lambda  returns the resulting value v � abstractions extend “as far to the right as possible. ” � v  The putChar function returns unit, so there is r x a b no interesting value to pass on. � 4


Recommend


More recommend