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

Similar documents
Scheme in Scheme: The Metacircular Evaluator Eval and Apply

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

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

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

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))

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

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

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

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

CS 314 Principles of Programming Languages. Lecture 16

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

Building a system for symbolic differentiation

A Brief Introduction to Scheme (II)

An Explicit-Continuation Metacircular Evaluator

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

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

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

Discussion 12 The MCE (solutions)

An Explicit Continuation Evaluator for Scheme

Building a system for symbolic differentiation

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

CS61A Midterm 2 Review (v1.1)

An Introduction to Scheme

User-defined Functions. Conditional Expressions in Scheme

Administrivia. Simple data types

CS 314 Principles of Programming Languages

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

YOUR NAME PLEASE: *** SOLUTIONS ***

Documentation for LISP in BASIC

CS450 - Structure of Higher Level Languages

6.001, Spring Semester, 1998, Final Exam Solutions Your Name: 2 Part c: The procedure eval-until: (define (eval-until exp env) (let ((return (eval-seq

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

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

Introduction to Functional Programming

4.2 Variations on a Scheme -- Lazy Evaluation

Sample Final Exam Questions

6.001, Spring Semester, 1998, Final Exam Your Name: 2 Question 1 (12 points): Each of the parts below should be treated as independent. For each part,

CS 275 Name Final Exam Solutions December 16, 2016

C311 Lab #3 Representation Independence: Representation Independent Interpreters

Introduction to Functional Programming in Racket. CS 550 Programming Languages Jeremy Johnson

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

Streams and Evalutation Strategies

Turtles All The Way Down

COP4020 Programming Assignment 1 - Spring 2011

Organization of Programming Languages CS3200/5200N. Lecture 11

First-class continuations. call/cc, stack-passing CEK machines

From Syntactic Sugar to the Syntactic Meth Lab:

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

11/6/17. Functional programming. FP Foundations, Scheme (2) LISP Data Types. LISP Data Types. LISP Data Types. Scheme. LISP: John McCarthy 1958 MIT

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

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

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

CS115 INTRODUCTION TO COMPUTER SCIENCE 1. Additional Notes Module 5

Comp 411 Principles of Programming Languages Lecture 7 Meta-interpreters. Corky Cartwright January 26, 2018

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

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

Functional Programming - 2. Higher Order Functions

An introduction to Scheme

Lecture #24: Programming Languages and Programs

Call with Current Continuation Patterns

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

FP Foundations, Scheme

Lexical vs. Dynamic Scope

CS 314 Principles of Programming Languages

Functional Programming. Pure Functional Languages

Structure and Interpretation of Computer Programs

CSc 520 Principles of Programming Languages

Recursive Functions of Symbolic Expressions and Their Computation by Machine Part I

INTRODUCTION TO SCHEME

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

Functional Programming. Pure Functional Languages

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

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

Scheme Basics > (butfirst '(help!)) ()

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Control in Sequential Languages

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

Structure and Interpretation of Computer Programs


Modern Programming Languages. Lecture LISP Programming Language An Introduction

(scheme-1) has lambda but NOT define

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Structure and Interpretation of Computer Programs

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

Comp 311: Sample Midterm Examination

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

Project 2: Scheme Interpreter

Continuations and Continuation-Passing Style

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

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

Programming Languages

Lisp. Versions of LISP

Scheme: Strings Scheme: I/O

CONCEPTS OF PROGRAMMING LANGUAGES Solutions for Mid-Term Examination

Konzepte von Programmiersprachen

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

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

Introduction to Scheme

Structure and Interpretation of Computer Programs

Transcription:

Deferred operations Continuations 6.037 - Structure and Interpretation of Computer Programs Mike Phillips <mpp> (define the-cons (cons 1 #f)) (set-cdr! the-cons the-cons) (define (run-in-circles l) (+ (run-in-circles (cdr l)))) Massachusetts Institute of Technology Lecture 7A (run-in-circles the-cons).. The program ran out of memory Mike Phillips <mpp> (MIT) Continuations Lecture 7A 1 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 2 / 21 Tail recursion in action Continuations (define the-cons (cons 1 #f)) (set-cdr! the-cons the-cons) (define (run-in-circles l) (run-in-circles (cdr l))) (run-in-circles the-cons) What if we never had any deferred operations? Instead of returning a value with deferred operations, the function is passed a continuation procedure, which we call to return a value Which means that all function calls are tail-recursive... Mike Phillips <mpp> (MIT) Continuations Lecture 7A 3 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 4 / 21

Simple CPS example Factorial in CPS (define (factorial n) (if (= n 0) 1 (* n (factorial (- n 1))))) (define (add-17 x) (+ x 17)) (define (add-17 x cont) (cont (+ x 17))) (define (factorial n cont) (if (= n 0) (cont 1) (factorial (- n 1) (lambda (x) (cont (* n x)))))) (factorial 10 (lambda (x) x)) No deferred operations We craft a new continuation, based on the previous one, and pass that to our recursive call Asks the question, What will I do with the return value of the recursive call? Multiply it by n, and call my continuation with that value Mike Phillips <mpp> (MIT) Continuations Lecture 7A 5 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 6 / 21 Sum-interval Append, done right (define (sum-interval a b) (if (= a b) a (+ a (sum-interval (+ a 1) b)))) (define (cs-sum-interval a b cont) (if (= a b) (cont a) (cs-sum-interval (+ a 1) b (lambda (x) (cont (+ a x)))))) (define (append L1 L2) (if (null? L1) L2 (cons (car L1) (append (cdr L1) L2)))) (define (cs-append L1 L2 cont) (if (null? L1) (cont L2) (cs-append (cdr L1) L2 (lambda (appended-cdr) (cont (cons (car L1) appended-cdr)))))) Mike Phillips <mpp> (MIT) Continuations Lecture 7A 7 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 8 / 21

Flatten Control flow (define (flatten tree) (cond ((null? tree) ()) ((not (pair? tree)) (list tree)) (else (append (flatten (car tree)) (flatten (cdr tree)))))) (define (cs-flatten tree cont) (cond ((null? tree) (cont ())) ((not (pair? tree)) (cont (list tree))) (else (cs-flatten (car tree) (lambda (car-leaves) (cs-flatten (cdr tree) (lambda (cdr-leaves) (cont (append car-leaves cdr-leaves) )))))))) Continuation-passing style is also very useful in controlling program flow Error handling and exceptions is a classic case: (define (divide a b success fail) (if (= b 0) (fail "divide-by-zero") (success (/ a b)))) Also asynchronous procedure calls Mike Phillips <mpp> (MIT) Continuations Lecture 7A 9 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 10 / 21 Continuations in the interpreter We can write a Scheme interpreter in continuation-passing style (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (if (eq? input **quit**) c-eval-done (c-eval input the-global-environment (lambda (output) (announce-output output-prompt) (display output) (driver-loop)))))) (define (c-eval exp env cont) (cond ((self-evaluating? exp) (cont exp)) ((variable? exp) (cont (lookup-variable-value exp env))) ((quoted? exp) (cont (text-of-quotation exp))) ((assignment? exp) (eval-assignment exp env cont)) ((definition? exp) (eval-definition exp env cont)) ((if? exp) (eval-if exp env cont)) ((lambda? exp) (cont (make-procedure (lambda-parameters exp) (lambda-body exp) env))) ((begin? exp) (eval-sequence (begin-actions exp) env cont)) ((cond? exp) (c-eval (cond->if exp) env cont))... Mike Phillips <mpp> (MIT) Continuations Lecture 7A 11 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 12 / 21

Continuations with the interpreter (define (eval-if exp env cont) (c-eval (if-predicate exp) env (lambda (test-value) (if test-value (c-eval (if-consequent exp) env cont) (c-eval (if-alternative exp) env cont))))) (define (eval-sequence exps env cont) (if (last-exp? exps) (c-eval (first-exp exps) env cont) (c-eval (first-exp exps) env (lambda (ignored) (eval-sequence (rest-exps exps) env cont))))) What if the evaluator made its continuations available to the language? call-with-current-continuation (a.k.a. call/cc) ;; Special form for evaluator (define (eval-call-with-current-continuation exp env cont) (c-eval (call/cc-proc exp) env (lambda (proc-to-call) (c-apply proc-to-call (list (make-continuation cont)) cont)))) ;; in c-apply ((continuation? procedure) (apply (continuation-internal-cont procedure) arguments)) Mike Phillips <mpp> (MIT) Continuations Lecture 7A 13 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 14 / 21 call/cc example call/cc explained (+ (* 3 (call-with-current-continuation (lambda (cont) (cont 5)))) 10) ; => 25 (define c #f) (+ (* 3 (call-with-current-continuation (lambda (cont) (set! c cont) (cont 5)))) 10) ; => 25 (c 6) ; => 28 (+ 100 (c 6)) ; => 28 call-with-current-continuation (or call/cc, as it is usefully shortened to) takes a procedure as an argument, and passes it the evaluator s current continuation The return value of call/cc is the same as the return value of the procedure... or the procedure could just call the continuation it was given. Which is exactly identical in meaning! The continuation of the call/cc expression, the continuation of the procedure that it calls, and the value that it passes as an argument to that procedure, are all the same! Mike Phillips <mpp> (MIT) Continuations Lecture 7A 15 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 16 / 21

Storing continuations Stored continuations can be saved away to jump back at any later point in time (define cont uninitialized) (if (call/cc (lambda (c) (set! cont c) #t)) something other-thing) ; => something (cont #f) ; => other-thing (define (fib-func) (let ((prev 0) (cur 1)) (define (loop) (define next (+ prev cur)) (set! prev cur) (set! cur next) prev) loop)) (define test (fib-func)) (test) ; => 1 (test) ; => 1 (test) ; => 2 (test) ; => 3 (test) ; => 5 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 17 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 18 / 21 (define resume uninitialized) (define (fib-cont) (let ((prev 0) (cur 1)) (define (loop) (define next (+ prev cur)) (set! prev cur) (set! cur next) (if (call/cc (lambda (c) (set! resume (lambda () (c #f))) (c #t))) prev (loop))) (loop))) (fib-cont) ; => 1 (resume) ; => 1 (resume) ; => 2 (resume) ; => 3 (resume) ; => 5 Coroutines Save the continuation, return true now But call the continuation with false again, sometime in the future, to take the other branch In this case, resumes the loop! This pattern is known as a coroutine Poor man s threading (running multiple things at once)... but we can do better... Mike Phillips <mpp> (MIT) Continuations Lecture 7A 19 / 21 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 20 / 21

Co-operative multithreading Only one bit of code can run at once, but we have multiple tasks to do Make each task declare when it s done doing some computation, and then swap Co-operative because tasks need to declare when they want to let someone else have a turn Used by Mac OS 9, Windows 3.1 Mike Phillips <mpp> (MIT) Continuations Lecture 7A 21 / 21