61A Lecture 30Wednesday, November 9Wednesday, November 9, 2011Functional ProgrammingAll functions are pure functionsNo assignment and no mutable data typesName-value bindings are permanentAdvantages of functional programming:•The value of an expression is independent of the order in which sub-expressions are evaluated•Sub-expressions can safely be evaluated in parallel or lazily•Referential transparency: The value of an expression does not change when we substitute one of its subexpression with the value of that subexpression.The subset of Logo we have considered so far is functional(except for print/show)2Wednesday, November 9, 2011The Logo Assignment ProcedureLogo binds variable names to values, as in PythonAn environment stores name bindings in a sequence of framesEach frame can have at most one value bound to a given name The make procedure adds or changes variable bindings3? make "x 2Values bound to names are looked up using variable expressions? print :x2DemoWednesday, November 9, 2011Namespaces for Variables and Procedures4x: 2FRAMES PROCEDURESsum :x :y<built-in>first :x<built-in>sum:first:make :n :v<built-in>make:...? make "sum 3sum: 3DemoWednesday, November 9, 2011Assignment RulesLogo assignment has different rules from Python assignment:5•If the name is already bound, make re-binds that name in the first frame in which the name is bound.•If the name is not bound, make binds the name in the global frame.? make <name> <value>Like non-local Python assignmentLike global Python assignmentWednesday, November 9, 2011Implementing the Make ProcedureThe implementation of make requires access to the environment6 def logo_make(symbol, val, env): env.set_variable_value(symbol, val)class Environment(object): def __init__(self, get_continuation_line=None): self.get_continuation_line = get_continuation_line self.procedures = load_primitives() self._frames = [dict()] # The first frame is global def set_variable_value(self, symbol, val): "*** YOUR CODE HERE ***"Wednesday, November 9, 2011Evaluating DefinitionsA procedure definition (to statement) creates a new procedure and binds its name in the table of known procedures7? to factorial :n> output ifelse :n = 1 [1] [:n * factorial :n - 1]> end class Procedure(): def __init__(self, name, arg_count, body, isprimitive=False, needs_env=False, formal_params=None): ...Formal parameters: a list of variable names (without colons)Body: a list of Logo sentencesWednesday, November 9, 2011Applying User-Defined ProceduresCreate a new frame in which formal parameters are bound to argument values, extending the current environmentEvaluate each line of the body of the procedure in the environment that starts with this new frameIf any top-level expression evaluates to a non-None value, raise an errorOutput values require special handling:•Output returns a pair: ('OUTPUT', <value>)•Stop returns a pair: ('OUTPUT', None)logo_apply returns the <value> that is output by the body8DemoWednesday, November 9, 2011PROCEDURESFRAMES...Dynamic Scope and EnvironmentsA new frame for an applied procedure extends the current frame9z: 13f :xmake "z sum :x :yf:g :x :yf sum :x :xg:x: 3gy: 7x: 6f? to f :x> make "z sum :x :y> end? to g :x :y> f sum :x :x> end? g 3 7? print :z13Dynamic scopingDemoWednesday, November 9, 2011FRAMESDynamic Scope and EnvironmentsThis example was presented in class on the chalkboard10y: 15triplex: 5x: 3triple? to triple :x> make "y product :x 3> output :y> end? to nonuple :y> output triple triple :y> end? print triple 515? print nonuple 327? print :y15x: 9triplenonupley: 3 9 27Wednesday, November 9, 2011An Analogy: Programs Define MachinesPrograms specify the logic of a computational device11factorial5 120=- factorial*111Wednesday, November 9, 2011Interpreters are General Computing MachineAn interpreter can be parameterized to simulate any machine12Logo Interpreter5 120to factorial :noutput ifelse :n = 1 [1] [:n * factorial :n - 1]endOur Logo interpreter is a universal machineA bridge between the data objects that are manipulated by our programming language and the programming language itselfInternally, it is just a set of manipulation rulesWednesday, November 9, 2011Interpretation in Pythoneval: Evaluates an expression in the current environment and returns the result. Doing so may affect the environment.exec: Executes a statement in the current environment. Doing so may affect the environment.13os.system('python <file>'): Directs the operating system to invoke a new instance of the Python interpreter.Demoeval('2 + 2')exec('def square(x): return x * x')Wednesday, November 9,
View Full Document