CS61A Notes Week 9: Muta4on (solu4ons) Revenge of the Box- and- pointers

Similar documents
PAIRS AND LISTS 6. GEORGE WANG Department of Electrical Engineering and Computer Sciences University of California, Berkeley

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

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

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

CS61A Midterm 2 Review (v1.1)

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


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

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

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

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

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

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

Fall 2017 December 4, 2017

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

Putting the fun in functional programming

Discussion 11. Streams

User-defined Functions. Conditional Expressions in Scheme

CS61A Notes Disc 11: Streams Streaming Along

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

YOUR NAME PLEASE: *** SOLUTIONS ***

More Scheme CS 331. Quiz. 4. What is the length of the list (()()()())? Which element does (car (cdr (x y z))) extract from the list?

Intro. Scheme Basics. scm> 5 5. scm>

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

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

Repetition Through Recursion

CS3: Introduction to Symbolic Programming. Lecture 14: Lists.

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

CS 314 Principles of Programming Languages

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

C311 Lab #3 Representation Independence: Representation Independent Interpreters

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

SCHEME AND CALCULATOR 5b

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

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

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

Introduction to Scheme

Sample Final Exam Questions

Lists in Lisp and Scheme

1.7 Limit of a Function

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

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

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

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

University of Massachusetts Lowell

CS 360 Programming Languages Day 14 Closure Idioms

Quicksort. Alternative Strategies for Dividing Lists. Fundamentals of Computer Science I (CS F)

Fifth Generation CS 4100 LISP. What do we need? Example LISP Program 11/13/13. Chapter 9: List Processing: LISP. Central Idea: Function Application

Fall 2017 December 4, Scheme. Instructions

CS3L Summer 2011 Final Exam, Part 2 You may leave when finished; or, you must stop promptly at 12:20

Functional Programming. Pure Functional Programming

CSC 533: Programming Languages. Spring 2015

6.001 recitation 3/21/07

CS61A Notes Disc 10: Vectors, concurrency Just When You Were Getting Used to Lists

PROBLEM SOLVING 11. July 24, 2012

Functional Programming. Pure Functional Languages

Homework 1. Notes. What To Turn In. Unix Accounts. Reading. Handout 3 CSCI 334: Spring, 2017

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

CONCEPTS OF PROGRAMMING LANGUAGES Solutions for Mid-Term Examination

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

6.001 Notes: Section 8.1

(scheme-1) has lambda but NOT define

Homework 1. Reading. Problems. Handout 3 CSCI 334: Spring, 2012

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

Problem 1. Remove consecutive duplicates (6 points, 11 mintues)

CS61A Notes Week 6: Scheme1, Data Directed Programming You Are Scheme and don t let anyone tell you otherwise

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

CS450 - Structure of Higher Level Languages

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

Simplifying Logical Formulas

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

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

Lisp. Versions of LISP

An Explicit-Continuation Metacircular Evaluator

CS 314 Principles of Programming Languages. Lecture 16

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

Administrivia. Simple data types

Functional Programming - 2. Higher Order Functions

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

A Brief Introduction to Scheme (II)

Vectors in Scheme. Data Structures in Scheme

by the evening of Tuesday, Feb 6

Important Example: Gene Sequence Matching. Corrigiendum. Central Dogma of Modern Biology. Genetics. How Nucleotides code for Amino Acids

CS 61A Discussion 8: Scheme. March 23, 2017

6.001 Notes: Section 31.1

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

CS 275 Name Final Exam Solutions December 16, 2016

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

Structure and Interpretation of Computer Programs

CSC324 Functional Programming Efficiency Issues, Parameter Lists

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

An Introduction to Scheme

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

Scheme as implemented by Racket

CS 314 Principles of Programming Languages

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Turtles All The Way Down

Transcription:

CS61A Notes Week 9: Muta4on (solu4ons) Revenge of the Box- and- pointers QUESTION We can also test if procedures are equal?. Consider this: > (define (square x) (* x x)) > (define (sqr x) (* x x)) > (eq? square sqr) => #f > (equal? square sqr) => #f It's obvious that square and sqr are not eq?. But they're also not equal? because for procedures, equal? does the same thing as eq?. Why can't we tell that square and sqr really do the same thing and thus, should be equal?? (Since you guys are always paranoid, no, this won't be on the test.) The problem wants to check that square and sqr are equal in the sense that, given the same input, they always return the same output. This is impossible, and has been proven to be impossible! (You will see more of this in CS70). Therefore the most we can do is compare whether two things are the same procedure, not whether they re the same function. QUESTION Draw box- and- pointer diagrams that show the structures v and w awer evalua4ng those expressions. What does Scheme print for the values of v and w? w => (d c b a) v => (a) Teenage Mutant Ninja... erm, Schemurtle (you try to do beyer) QUESTIONS 1. Personally and don t let this leave the room I think set-car! and set-cdr! are useless; we can just implement them using set!. Check out my two proposals for set-car!. Do they work, or do they work? Prove me wrong: a. (define (set-car! thing val) b. (set! (car thing) val)) c. d. Doesn t work set! is a special form! It cannot evaluate what (car thing) is. a. (define (set-car! thing val) b. (let ((thing-car (car thing))) c. (set! thing-car val))) d.

e. Doesn t work. thing-car is a new symbol bound to the value of (car thing), and the set! statement simply sets the value of thing-car to val, without touching the original thing at all. 1. I d like to write a procedure that, given a deep list, destruc4vely changes all the atoms into the symbol scheme: 2. > (define ls (1 2 (3 (4) 5))) 3. > (glorify! ls) => return value unimportant 4. > ls => (scheme scheme (scheme (scheme) scheme)) 5. Here s my proposal: 6. (define (glorify! L) 7. (cond ((atom? L) 8. (set! L scheme)) 9. (else (glorify! (car L)) 10. (glorify! (cdr L))))) 11. 12. Does this work? Why not? Write a version that works. 13. 14. No. Remember, to manipulate elements of a list, you need to use set-car! or set-cdr!. set! sets ls to scheme when ls is an atom, but once we return, the new value for ls is lost. Here s a way to do this: (define (glorify! ls) (cond ((null? ls) ()) ((atom? ls) chung) (else (set-car! ls (glorify! (car ls))) (set-cdr! ls (glorify! (cdr ls))) ls))) We need to return ls because the set-car! and set-cdr! expressions expect glorify! to return something namely, the transformed sublist. 1. We d like to rid ourselves of odd numbers in our list: 2. (define my-lst (1 2 3 4 5)) a. Implement (no-odd! ls) that takes in a list of numbers and returns the list without the odds, using muta:on: b. (no-odd! my-lst) => (2 4) c. d. (define (no-odd! ls) e. (cond ((null? ls) ()) f. ((odd? (car ls)) (no-odd! (cdr ls))) g. (else (set-cdr! ls (no-odd! (cdr ls))) h. ls))) a. Implement (no-odd! ls) again. This 4me, it s4ll takes in a list of numbers, but can return anything. But awer the call, the original list should be mutated so that it contains no odd numbers. Or,

b. (no-odd! my-lst) => return value unimportant c. my-lst => (2 4) d. (Try to consider if this is possible before you start!) e. f. This, I fear, is not possible. Note that we need to skip the first element (the 1), so we d like to do something like (set! my-lst...) to have it point to the solution instead of the cons pair containing 1 as the car. However, inside the procedure noodd!, we have no way of doing that; we can set! ls to all our heart s content, but we have no way of altering the value of my-lst. Make sure you understand why; this point is crucial. g. h. There is hope with use of sentinels. If we always represent lists like so: i. j. (define (new-list first. rest) k. (cons #f (cons first rest))) l. m. where (new-list 1 2 3 4 5) => (#f 1 2 3 4 5), then we can do this: n. o. (define (no-odd! ls) p. (cond ((null? ls) ()) q. ((null? (cdr ls)) ls) r. ((odd? (cadr ls)) (set-cdr! ls (no-odd! (cddr ls))) ls) s. (else (set-cdr! ls (no-odd! (cdr ls))) ls))) t. u. Carefully consider how the new representation of lists allowed us to do that. What we wanted to be able to do was to have my-lst point to something else (other than the pair containing 1). But we had no way to do that. So instead, we have my-lst point to some useless thing like a pair containing #f and, with that, we ll be able to set! the first element of the list to something else. If that s clear as mud, draw a few box-and-pointer diagrams! v. w. We used the word sentinel to refer to #f. A sentinel is a meaningless value at the start of a data structure that allows us to do what we did above. It also makes the code look prettier, as in the remove! procedure presented in lecture. 1. It would also be nice to have a procedure which, given a list and an item, inserts that item at the end of the list by making only one new cons cell. The return value is

unimportant, as long as the element is inserted. In other words, 2. > (define ls (1 2 3 4)) 3. > (insert! ls 5) => return value unimportant 4. > ls => (1 2 3 4 5) 5. Does the following procedure work? If not, can you write one that does? 6. (define (insert! L val) 7. (if (null? L) 8. (set! L (list val)) 9. (insert! (cdr L) val))) 10. 11. Nope; this should be automatic by now: set! does not change elements or structure of a list! As for glorify!, you might try returning partial answers like this: 12. 13. (define (insert! ls val) 14. (cond ((null? ls) (list val)) 15. (else (set-cdr! ls (insert! (cdr ls) val)) 16. ls))) 17. 18. (define ls (1 2 3 4)) 19. (insert! ls 5) => (1 2 3 4 5) 20. ls => (1 2 3 4 5) 21. 22. This almost works. But what if ls is null? 23. 24. (define ls ()) 25. (insert! ls 3) => (3) 26. ls => () 27. 28. Why doesn t this work? Think carefully. The answer lies in #3b. 1. Write a procedure, remove-first! which, given a list, removes the first element of the list destruc:vely. You may assume that the list contains at least two elements. So, 2. > (define ls (1 2 3 4)) 3. > (remove-first! ls) => return value unimportant 4. > ls => (2 3 4) 5. And what if there s only one element? 6. From 3 and 4, we know that we can t change what ls points, and so we can t do it the obvious way: 7. 8. (define (remove-first! L) 9. (set! L (cdr L))) 10. 11. This doesn t work for reasons we mentioned in 2. Instead, our strategy will be to copy all the elements up one spot, and cut off the cons cell at the end of the list rather than the beginning: 12.

13. (define (remove-first! L) 14. (cond ((null? (cdr (cdr L))) 15. (set-car! L (cadr L)) 16. (set-cdr! L ())) 17. (else (set-car! L (cadr L)) 18. (remove-first! (cdr L))))) 19. 20. Note that having at least two elements in the list allows us to do (cdr (cdr ls)) in the base case. If there s only one element, this wouldn t work, and in fact there s no general procedure that can remove the first element given any list. Consider: 21. 22. (define ls (1)) 23. (remove-first! ls) 24. ls => () 25. 26. This means we ll need to change what ls points to (from a cons cell to a null list), which we know we can t do from within remove-first!. 1. Implement our old friend's ruder cousin, (reverse! ls). It reverses a list using muta:on. (This is a standard programming job interview ques:on.) 2. 3. ;; here s a way using state 4. (define (reverse! ls) 5. (define (helper! prev rest) 6. (cond ((null? rest) prev) 7. (else (let ((rest-of-rest (cdr rest))) 8. (set-cdr! rest prev) 9. (helper! rest rest-of-rest))))) 10. (helper! () ls)) 11. 12. ;; this way is similar to the way we approached the old reverse 13. ;; problem; reverse! the rest of the list, and then attach the 14. ;; first element to the last 15. (define (reverse! ls) 16. (define (last ls) 17. (cond ((null? ls) '()) 18. ((null? (cdr ls)) ls) 19. (else (last (cdr ls))))) 20. (cond ((null? ls) ()) 21. ((null? (cdr ls)) ls) 22. (else (let ((rest-reversed (reverse! (cdr ls)))) 23. (set-cdr! ls ()) 24. (set-cdr! (last rest-reversed) ls)

25. rest-reversed)))) 1. Implement (deep-map! proc deep-ls) that maps a procedure over every element of a deep list, without alloca:ng any new cons pairs. So, 2. (deep-map! square (1 2 (3 (4 5) (6 (7 8)) 9))) => 3. (1 4 (9 (16 25) (36 (49 64)) 81)) 4. 5. (define (deep-map! proc ls) 6. (cond ((null? ls) ()) 7. ((not (pair? ls)) (proc ls)) 8. (else (set-car! (deep-map! proc (car ls))) 9. (set-cdr! (deep-map! proc (cdr ls)))))) 1. Implement (interleave! ls1 ls2) that takes in two lists and interleaves them without alloca4ng new cons pairs. 2. 3. (define (interleave! ls1 ls2) 4. (cond ((null? ls1) ls2) 5. ((null? ls2) ls1) 6. (else (set-cdr! ls1 (interleave! ls2 (cdr ls1))) 7. ls1)))