Normal Order (Lazy) Evaluation SICP. Applicative Order vs. Normal (Lazy) Order. Applicative vs. Normal? How can we implement lazy evaluation?

Similar documents
6.037 Lecture 7B. Scheme Variants Normal Order Lazy Evaluation Streams

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Lexical vs. Dynamic Scope

Streams. CS21b: Structure and Interpretation of Computer Programs Spring Term, 2004

CS450 - Structure of Higher Level Languages

4.2 Variations on a Scheme -- Lazy Evaluation

Streams and Evalutation Strategies

CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

CS61A Midterm 2 Review (v1.1)

Review Analyzing Evaluator. CS61A Lecture 25. What gets returned by mc-eval? (not analyzing eval) REVIEW What is a procedure?

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream?

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream? 2. How does memoization work?

Discussion 12 The MCE (solutions)

Building a system for symbolic differentiation

6.001 Notes: Section 17.5

An introduction to Scheme

ITERATORS AND STREAMS 9

CS61A Notes Disc 11: Streams Streaming Along

Using Symbols in Expressions (1) evaluate sub-expressions... Number. ( ) machine code to add

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

This exam is worth 70 points, or about 23% of your total course grade. The exam contains 15 questions.

An Explicit-Continuation Metacircular Evaluator

Building a system for symbolic differentiation

Lazy Evaluation and Parameter Transfer

6.001: Structure and Interpretation of Computer Programs

Discussion 11. Streams

CSc 520 Principles of Programming Languages

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

Problem Set 4: Streams and Lazy Evaluation

Building up a language SICP Variations on a Scheme. Meval. The Core Evaluator. Eval. Apply. 2. syntax procedures. 1.

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

Overview. CS301 Session 3. Problem set 1. Thinking recursively

COP4020 Programming Assignment 1 - Spring 2011

Administrivia. Simple data types

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Scheme Quick Reference

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

(scheme-1) has lambda but NOT define

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

1.3. Conditional expressions To express case distinctions like

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Scheme Quick Reference

Syntactic Sugar: Using the Metacircular Evaluator to Implement the Language You Want

Functional Programming. Pure Functional Programming

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

cs61amt2_4 CS 61A Midterm #2 ver March 2, 1998 Exam version: A Your name login: cs61a- Discussion section number TA's name

A Brief Introduction to Scheme (II)

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

CS 61A, Fall, 2002, Midterm #2, L. Rowe. 1. (10 points, 1 point each part) Consider the following five box-and-arrow diagrams.

Func%onal Programming in Scheme and Lisp

CS 360 Programming Languages Interpreters

Racket: Macros. Advanced Functional Programming. Jean-Noël Monette. November 2013

CS 314 Principles of Programming Languages. Lecture 16

Project 2: Scheme Interpreter

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Func%onal Programming in Scheme and Lisp

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Class 6: Efficiency in Scheme


6.034 Artificial Intelligence February 9, 2007 Recitation # 1. (b) Draw the tree structure corresponding to the following list.

LECTURE 16. Functional Programming

CS 342 Lecture 8 Data Abstraction By: Hridesh Rajan

MASSACHVSETTS INSTITVTE OF TECHNOLOGY Department of Electrical Engineering and Computer Science. Issued: Wed. 26 April 2017 Due: Wed.

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

Organization of Programming Languages CS3200/5200N. Lecture 11

CS 61A Midterm #2 ver March 2, 1998 Exam version: A. Your name. login: cs61a- Discussion section number. TA's name

From Syntactic Sugar to the Syntactic Meth Lab:

Fall Semester, Lecture Notes { November 12, Variations on a Scheme Nondeterministic evaluation

CS115 INTRODUCTION TO COMPUTER SCIENCE 1. Additional Notes Module 5

(Func&onal (Programming (in (Scheme)))) Jianguo Lu

CS 275 Name Final Exam Solutions December 16, 2016

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Extra Lecture #7: Defining Syntax

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

CSC 533: Programming Languages. Spring 2015

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

Functional Programming. Big Picture. Design of Programming Languages

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

6.001, Fall Semester, 1998 Lecture Notes, October 27 { Object Oriented Programming 2 An environment diagram illustrating +define foo +cons 1 2,, +set-

An Explicit Continuation Evaluator for Scheme

Lists in Lisp and Scheme

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

An Introduction to Scheme

CS 314 Principles of Programming Languages

Code example: sfact SICP Explicit-control evaluator. Example register machine: instructions. Goal: a tail-recursive evaluator.

Lecture 5: Lazy Evaluation and Infinite Data Structures

CS61A Notes 02b Fake Plastic Trees. 2. (cons ((1 a) (2 o)) (3 g)) 3. (list ((1 a) (2 o)) (3 g)) 4. (append ((1 a) (2 o)) (3 g))

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Sample Final Exam Questions

INTRODUCTION TO SCHEME

Programming Languages. Streams Wrapup, Memoization, Type Systems, and Some Monty Python

Principles of Programming Languages

Mid-Term 2 Grades

Transcription:

Normal Order (Lazy) Evaluation Alternative models for computation: Normal (Lazy) Order Evaluation Memoization Streams Applicative Order: evaluate all arguments, then apply operator Normal Order: pass unevaluated ression to function evaluate only when needed for primitive operation 1 2 Applicative Order vs. Normal (Lazy) Order Applicative vs. Normal? (define (foo x) (write-line "") (+ x x)) (define (try a b) (if (= a 0) 1 b)) (foo (begin (write-line "") 222)) (try 0 (/ 1 0)) Applicative Order: We first evaluated argument, then substituted value into the body of the procedure Normal (Lazy) Order: As if we substituted the unevaluated ression in the body of the procedure 3 (try 0 (pi-to-this-many-digits 10000000)) 4 Exercise Problem with Applicative Order Why cant we use define to define any special form? E.g write a procedure safe/ that only divide if b <> 0 (define (unless pred usual exc) (if pred exc usual)) (define (safe/ a b) (unless (= b 0) (/ a b) 0) (define (safe/ a b) (cond ((= b 0) 0) (else (/ a b)))) How can we implement lazy evaluation? (define (l-apply procedure arguments ) ; changed (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure (list-of-arg-values arguments ))) ((compound-procedure? procedure) (l-eval-sequence (procedure-body procedure) (extend-ironment (procedure-parameters procedure) (list-of-delayed-args arguments ) (procedure-ironment procedure)))) (else (error "Unknown proc" procedure)))) 5 6

Thunks a delayed argument Abstractly a thunk is a "promise" to return a value when later needed ("forced") Concretely our representation: thunk (delay-it ) promise to eval later (force-it ) eval now, leave no thunks Thunks delay-it and force-it (define (delay-it ) (list 'thunk )) (define (thunk? obj) (tagged-list? obj 'thunk)) (define (thunk- thunk) (cadr thunk)) (define (thunk- thunk) (caddr thunk)) (cond ((thunk? obj) (thunk- obj))) (define (actual-value ) (force-it (l-eval ))) 7 8 Exercise Applicative vers Normal Order Write a function normal-order? That returns #t if the language is normal order and #f if the language is applicative order. (define (normal-order?) (let ((x #t)) ((lambda (x) ()) (begin (set! x #f) ())) x)) Memo-izing evaluation In lazy evaluation an arg is reevaluate each time it is used In applicative order evaluation argument is evaluated once Can we keep track of values once we ve obtained them, and avoid cost of reevaluation? thunk 9 evaluatedthunk result 10 Thunks Memoizing Implementation (define (evaluated-thunk? obj) (tagged-list? obj 'evaluated-thunk)) (define (thunk-value evaluated-thunk) (cadr evaluated-thunk)) (cond ((thunk? obj) (let ((result (thunk- obj)))) (set-car! obj 'evaluated-thunk) (set-car! (cdr obj) result) (set-cdr! (cdr obj) '()) result)) ((evaluated-thunk? obj) (thunk-value obj)) Laziness and Language Design We have a dilemma with lazy evaluation Advantage: only do work when value actually needed Disadvantages not sure when ression will be evaluated; can be very big issue in a language with side effects may evaluate same ression more than once Memoization doesn't fully resolve our dilemma Advantage: Evaluate ression at most once Disadvantage: What if we want evaluation on each use? Alternative approach: give programmer control! 11 12

Variable Declarations: lazy and lazy- memo Handle lazy and lazy-memo extensions in an upwardcompatible fashion.; (lambda (a (b lazy) c (d lazy-memo))...) "a", "c" are the usual kind of variables (evaluated before procedure application "b" is lazy, Normal Order : it gets (re)-evaluated each time its value is actually needed "d" is lazy-memo; it gets evaluated the first time its value is needed, and then that value is returned again any other time it is needed again. Syntax Extensions Parameter Declarations (define (first-variable var-decls) (car var-decls)) (define (rest-variables var-decls) (cdr var-decls)) (define declaration? pair?) (define (parameter-name var-decl) (if (pair? var-decl) (car var-decl) var-decl)) (define (lazy? var-decl) (and (pair? var-decl) (eq? 'lazy (cadr var-decl)))) (define (memo? var-decl) (and (pair? var-decl) (eq? 'lazy-memo (cadr var-decl)))) 13 14 Controllably Memo-izing Thunks A new version of delay-it thunk thunk-memo evaluated-thunk when forced never gets memoized first eval is remembered memoized-thunk that has already been evaluated thunkmemo Look at the variable declaration to do the right thing... (define (delay-it decl ) (cond ((not (declaration? decl)) (l-eval )) ((lazy? decl) (list 'thunk )) ((memo? decl) (list 'thunk-memo )) (else (error "unknown declaration:" decl)))) evaluatedthunk result 15 16 Change to force-it (cond ((thunk? obj) ;eval, but don't remember it (thunk- obj))) ((memoized-thunk? obj) ;eval and remember (let ((result (thunk- obj)))) (set-car! obj 'evaluated-thunk) (set-car! (cdr obj) result) (set-cdr! (cdr obj) '()) result)) ((evaluated-thunk? obj) (thunk-value obj)) Order Comparison (define (foo x) (write-line "") (+ x x)) (foo (begin (write-line "") 222)) Applicative Order: Normal (lazy) Order: Memoized Normal (Lazy-memo) Order: 17 18

Exercise Stream Object Given this definition of l-abs: (define (l-abs (i lazy)) (if (< i 0) (- i) i)) A pair-like object, except the cdr part is lazy (not evaluated until needed): cons-stream Trace the following use of l-abs: (define (down) (begin (set! x (- x 2)) x) (define x 3) (l-abs (down)) stream-car a value (define x (y lazy-memo)) (cons x y)) (define stream-car car) (define stream-cdr cdr) stream-cdr a thunk-memo 19 20 What will these print? (ex1) (define s (cons 5 (begin (write-line 7) 9))) (car s) (cdr s) (define t 5 (begin (write-line 7) 9))) (stream-car t) (stream-cdr t) Can separate order of events in computer from apparent order of events in procedure description (list-ref (filter (lambda (x) (prime? x)) (enumerate-interval 1 100000000)) 100) (stream-ref (stream-filter (lambda (x) (prime? x)) (stream-interval 1 100000000)) 100) 21 22 (define (stream-interval a b) (if (> a b) the-empty-stream a (stream-interval (+ a 1) b)))) (define (filter-stream pred str) (if (pred (stream-car str)) (stream-car str) (filter-stream pred (stream-cdr str))) (filter-stream pred (stream-cdr str)))) (define seq (stream-interval 1 10)) (define y (stream-filter even? seq)) Now! Lets do some calculation... (stream-ref y 3) -> 8 23 24

Creating streams There are two basic ways to create streams: Creating infinite streams (define ones s 1 ones)) 1. Build them up from scratch 2. Modify or combine existing streams (define (add-streams s1 s2) (+ (stream-car s1) (stream-car s2)) (add-streams (stream-cdr s1) (stream-cdr s2))))) (define integers 1 (add-streams ones integers)) 25 26 Creating fibonacci streams (ex4) Creating fibonacci streams Write a procedure, (fibs), that returns a stream of Fibonacci numbers. The Fibonacci series goes Write a procedure, (fibs), that returns a stream of Fibonacci numbers. The Fibonacci series goes (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765...) (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765...) It starts with two 1's, then each successive value is the sum of the previous two. It starts with two 1's, then each successive value is the sum of the previous two. (define fibs 0 1 (add-stream (stream-cdr fibs) fibs)))) 27 28 Add-Streams == Map2 (add-streams integers integers) == (map2-stream + integers integers) (define (map2-stream proc str1 str2) (proc (stream-car str1) (stream-car str2)) (map-stream2 proc (stream-cdr str1) (stream-cdr str2)))) 29