CSC302 2005S, Class 13: More Scheme Semantics Admin: * Sleep rather than get stuff in on time * New late policy: If you start stuff early (at least a day in advance) and go to bed by 1 a.m., you can have a free extension on homework. (Send me a note that you've done so.) * No class Friday * Syllabus rearranged: Take-home exam replaces in-class exam * Extra credit for attending "Tangles and links" on Wednesday * No office hours today or Wednesday Overview: * Questions * Unpacking set! * Unpacking function application * More ... Any questions? Quiz: Explain the roles of assign, lookup, and single in scriptE[[(set! I E)]] = \ rho kappa . scriptE[[E]] rho (single (\e . assign (lookup rho I) e (send unspecified kappa))) * Expectation: Evaluate the expression, look up the location associated with I, store the value in that location * Given that memory (store) is a function from L to (E x T), what does it mean to "store a value in that location"? Update the function so that it now maps the location to that new value. * Where does the store appear here? * It's returned from assign * Where does assign get the store it modifies? Detour: * assign: L -> E -> C -> C * assign = \ alpha e theta sigma * How? * C = S -> A * assign: L -> E -> C -> S -> A * assign = \ alpha e theta sigma * Answer to the earlier question: * The store comes from the command continuation * assign is called with only three of its four parameters, giving us a function that expects a store Detour: * Functions of many parameters that are recast as functions of one parameter to functions of one parameter to functions of one parameter (etc.) are called "Curried" functions. * Invented by a logician named Haskell B. Curry scriptE[[(set! I E)]] = \ rho kappa . scriptE[[E]] rho (single (\e . assign (lookup rho I) e (send unspecified kappa))) * What are the normal "parameters" to scriptE[[E]]: rho: Environment kappa: Expression continuation (also hidden): Returns command continuation, which is S -> A * We evaluate E in the same environment (rho doesn't change) * We then "call" (single ...) on that expression What does single do here? * Makes an expression continuation from a single-parameter function. * Adds verification that the ec is called with only one param. Why is single necessary? * Expression continuations map E* to C You would never want to say scriptE*[[E1 E2]] rho \e . whatever Steps in deconstructing this notation: * What do I expect it to do? * Where do I see the pieces of my answer to the previous question? * What role do all the parameters play? * What things are particularly strange? * What seems to 'change' and what doesn't? Along the way * What types play a role? * What auxiliary functions play a role? ScriptE[[(E0 E*)]] * What do I expect it to do? * Given 1 or more expressions, * The first of which is a function, * Evaluate E0 and all of E* * Make sure that E* has the right number of values for E0 * Apply the first expression to the remainder Be ready to go through first lambda and sequence If I get no questions, you get a quiz