Loops in Scheme, II c. Kathi Fisler, 2001 (early slides assume map/filter)

Slides:



Advertisements
Similar presentations
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 5. 2 List Utilities Scheme built-in procedures –(list x y z...) –(list-ref lst index) –(length lst) –(append.
Advertisements

CSC 270 Nov. 22, 2005 Last Day of Scheme Dr. Stephen Bloch
Higher-Order Functions and Loops c. Kathi Fisler,
F28PL1 Programming Languages Lecture 14: Standard ML 4.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
CSE 341 Lecture 16 More Scheme: lists; helpers; let/let*; higher-order functions; lambdas slides created by Marty Stepp
CS 116 Tutorial 2 Functional Abstraction. Reminders Assignment 2 is due this Wednesday at Noon.
Developing Programs for Family Trees c. Kathi Fisler, 2001.
Developing Programs for Family Trees c. Kathi Fisler, 2001.
Types of the past exam questions I. Write/Complete Code II. Evaluate Expressions III. Analyze Complexity IV. Meta-circular Evaluator.
מבוא מורחב - שיעור 10 1 Symbols Manipulating lists and trees of symbols: symbolic differentiation Lecture 10.
מבוא מורחב - שיעור 81 Lecture 8 Lists and list operations (continue).
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Ormap, andmap, and filter CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.3 TexPoint fonts used in EMF. Read the TexPoint manual before you delete.
Rewriting your function using map and foldr CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.5 TexPoint fonts used in EMF. Read the TexPoint manual.
General pattern for selecting some elements of a list This negatives example illustrates a general pattern: If you want a function which selects some elements.
CS116 – Tutorial 3 Accumulative Recursion/Runtime.
From Templates to Folds CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under a Creative Commons.
Foldr CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.4 TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AAA © Mitchell.
Local Definitions, Scope, Functional Abstraction, and Polymorphism.
Arbitrarily Long Data Structures: Lists and Recursion CMSC Introduction to Computer Programming October 4, 2002.
Functional Programming in Scheme and Lisp. Overview In a functional programming language, functions are first class objects. You can create them, put.
Functional Programming and Lisp. Overview In a functional programming language, functions are first class objects. In a functional programming language,
Functional Programming in Scheme and Lisp.
Function Design in LISP. Program Files n LISP programs are plain text –DOS extensions vary; use.lsp for this course n (load “filename.lsp”) n Can use.
Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Introduction to Computer Science I Topic 8: Accumulating.
Abstraction: Procedures as Parameters CMSC Introduction to Computer Programming October 14, 2002.
Rewriting your function using map and foldr CS 5010 Program Design Paradigms “Bootcamp” Lesson TexPoint fonts used in EMF. Read the TexPoint manual.
CS116 Tutorial 1 Review of CS115. Reminders Assignment 1 is due Wednesday, January 21th at 12pm (Noon) Submit Assignment 0 if you have not done so already.
Milos Hauskrecht (PDF) Hieu D. Vu (PPT) LISP PROGARMMING LANGUAGE.
Lecture on Set! And Local CS 2135 Copyright Kathi Fisler, 2002 This material requires Advanced Language Level.
Fall 2008Programming Development Techniques 1 Topic 8 Sequences as Conventional Interfaces Section October 2008.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 6. 2 List Utilities Scheme built-in procedures –(list x y z...) –(list-ref lst index) –(length lst) –(append.
Forms Writing your own procedures CS 480/680 – Comparative Languages.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
Spring 16 CSCI 4430, A Milanova/BG Ryder 1 Announcements HW5 due March 28 Homework Server link is up I will have office hours, Fri or Mon, check Announcements.
1 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson.
1 Recursive Data Structures CS 270 Math Foundations of CS Jeremy Johnson.
Lets and Loops Tail Recursion.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
CS 550 Programming Languages Jeremy Johnson
Class 11: Two-argument recursion
PPL Lecture Notes: Chapter 3 High-Order Procedures Revisited.
The interpreter.
Racket CSC270 Pepper major portions credited to
From Templates to Folds
CS 270 Math Foundations of CS Jeremy Johnson
Introduction to Functional Programming in Racket
6.001 SICP Data abstractions
Higher-Order Procedures
CS 5010 Program Design Paradigms “Bootcamp” Lesson 7.5
PROGRAMMING IN HASKELL
The Metacircular Evaluator
The Metacircular Evaluator
Lecture #8 מבוא מורחב.
(early slides assume map/filter)
The Metacircular Evaluator (Continued)
Streams, Delayed Evaluation and a Normal Order Interpreter
Let's Play "What's the Question"
Introduction to Functional Programming in Racket
HIGHER ORDER FUNCTIONS
Announcements Quiz 5 HW6 due October 23
List and list operations (continue).
Today’s topics Abstractions Procedural Data
6.001 SICP Interpretation Parts of an interpreter
ormap, andmap, and filter
Developing Programs for Family Trees
Rewriting your function using map and foldr
Presentation transcript:

Loops in Scheme, II c. Kathi Fisler, 2001 (early slides assume map/filter)

Recap: filter and map filter and map are Scheme’s “loops” –filter : (   boolean) list[  ]  list[  ] extract list of elts that satisfy a predicate –map : (    ) list[  ]  list[  ] applies function to all elts, returning list of results

Recall sum ;; sum : list[num]  num ;; adds up the elements of a list of numbers (define (sum alon) (cond [(empty? alon) 0] [(cons? alon) (+ (first alon) (sum (rest alon)))])) Sum also loops; how to write it with filter/map? [try it]

filter/map don’t work for sum Both return lists -- sum returns a number Sum requires another kind of loop We derived filter by looking at two programs with similar structure and abstracting the common parts into a helper function …

sum and product ;; sum : list[num]  num ;; adds elts of a list of nums (define (sum alon) (cond [(empty? alon) 0] [(cons? alon) (+ (first alon) (sum (rest alon)))])) ;; prod : list[num]  num ;; multiplies list of nums (define (prod alon) (cond [(empty? alon) 1] [(cons? alon) (* (first alon) (prod (rest alon)))])) Where do these two programs differ?

sum and product ;; sum : list[num]  num ;; adds elts of a list of nums (define (sum alon) (cond [(empty? alon) 0] [(cons? alon) (+ (first alon) (sum (rest alon)))])) ;; prod : list[num]  num ;; multiplies list of nums (define (prod alon) (cond [(empty? alon) 1] [(cons? alon) (* (first alon) (prod (rest alon)))])) Make the blue parts parameters to a new function [try it]

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Write sum and product using newloop [try it]

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; sum : list[num]  num (define (sum alon) (newloop + 0 alon) ;; prod : list[num]  num (define (prod alon) (newloop * 1 alon)

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Write length (of a list) using newloop [try it] base and alon arguments are easy … but combine …

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? [try it] ;; combine : (we see from its use that it takes two arguments) 

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What type is (first alon)?  A number, by contract

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What type is (first alon)?  A number, by contract num

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What type is (newloop (rest alon))?  A number, by contract num

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What type is (newloop (rest alon))?  A number, by contract num

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What does combine return?  num A number (by contract) since newloop returns the result of combine

The “New Loop” ;; newloop : ? num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What is combine’s contract? ;; combine : What does combine return?  A number (by contract) since newloop returns the result of combine num

The “New Loop” ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) So, combine has contract ;; combine : num num  num OK, but how do we write combine for length?

The “New Loop” ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Combine takes the first elt of the list and the result of looping on the rest of the list. So, your combine function determines how to put these together …

The “New Loop” ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; combine : num num  num (lambda (elt result-rest) …) (this naming convention on combine functions reminds you what the args stand for)

The “New Loop” ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; combine : num num  num (lambda (elt result-rest) (+ 1 result-rest)) For length, we don’t care about the contents of the elt, just that it exists. Combine therefore ignores elt.

The “New Loop” ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) [stretch break]

But wait … ;; newloop : (num num  num) num list[num]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) The contracts don’t match!

Fixing the newloop contract ;; newloop : (num num  num) num list[  ]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) If we change num to , what else must change in the newloop contract?

Fixing the newloop contract ;; newloop : (num num  num) num list[  ]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) Where is the  processed in newloop?

Fixing the newloop contract ;; newloop : (  num  num) num list[  ]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) So the first argument to combine must also be 

Fixing the newloop contract ;; newloop : (  num  num) num list[  ]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) ;; length : list[  ]  num (define (length alst) (newloop (lambda (elt result-rest) (+ 1 result-rest)) 0 alst)) This fixes the contract wrt length; now consider newloop alone

Stepping back: newloop ;; newloop : (  num  num) num list[  ]  num (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) What in the definition of newloop requires it to output a number? (newloop has no arith ops…) What if we wanted a loop that returned a boolean, or a structure, or …?

Generalizing newloop ;; newloop : (  num  num) num list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ?

Generalizing newloop ;; newloop : (  num  num) num list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? Where does the output of newloop come from?

Generalizing newloop ;; newloop : (  num  num) num list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? Where are these types in the contract?

Generalizing newloop ;; newloop : (  num   )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? Change these types to 

Generalizing newloop ;; newloop : (  num   )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? What about that lingering num? (where is it from)?

Generalizing newloop ;; newloop : (  num   )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? The num is the second argument to combine

Generalizing newloop ;; newloop : (  num   )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? But this value comes from the output of newloop!

Generalizing newloop ;; newloop : (     )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Let’s change the contract to let newloop return a value of any type. What else in the contract must change to  ? So this num must also become a 

At long last … ;; newloop : (     )  list[  ]   (define (newloop combine base alon) (cond [(empty? alon) base] [(cons? alon) (combine (first alon) (newloop (rest alon)))])) Actually, newloop is built-in. It’s called foldr

The foldr loop ;; foldr : (     )  list[  ]   (define (foldr combine base alst) (cond [(empty? alst) base] [(cons? alst) (combine (first alst) (foldr (rest alst)))])) ;; length : list[  ]  num (define (length alst) (foldr (lambda (elt result-rest) (+ 1 result-rest)) 0 alon))

Phew! We now have three loops at our disposal: –filter : (   boolean) list[  ]  list[  ] extract list of elts that satisfy a predicate –map : (    ) list[  ]  list[  ] applies function to all elts, returning list of results –foldr : (     )  list[  ]   combines elts of list according to given function

Time to practice! Recall the data defns for animal/boa/armadillo ;; A boa is a (make-boa symbol num symbol) (define-struct boa (name length food)) ;; An armadillo is a (make-dillo symbol num bool) (define-struct dillo (name length dead?)) ;; An animal is one of ;; - a boa ;; - an armadillo

Time to practice! Write the following programs with Scheme loops ;; large-animals : list[animal] num  list[animal] ;; return list of all animals longer than given num ;; eats-pets-count : list[animal]  num ;; return number of boas in list that eat pets ;; kill-all-dillos : list[animal]  list[animal] ;; return list containing all animals in the input list ;; but with all armadillos dead