Functional Problem Solving (CSC 151 2016S) : EBoards
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Taking Notes] [Rubric]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Labs] [Outlines] [Readings] - [Examples] [Handouts]
Reference: [Setup] [Remote] [VM] [Errors] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Curtsinger (2016S)] [Davis (2013F)] [Rebelsky (2015F)] [Weinman (2014F)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)]
Thank you to the students who showed up so that we'll have notes that that other students can read over later.
Finding This Page
Notes
Overview
Topics
Types of questions
Can we compare list recursion and numeric recursion?
When we think about list recursion, we have two basic parts to every recursive function. (There may be multiple versions of each part.)
"Base case": Empty list, singleton list, identified value if we're just looking for the first one, etc.
"Simplify for recursive case": Take the cdr.
For numeric recursion, we also have base cases and recursive cases.
"Base case": 0, 1, n (if counting up), "close enough to some goal" (e.g., if we are approximating the square root of 2 with successive approximations)
"Simplify for the recursive case": Subtract 1 (counting down to 0 or 1), add 1 (counting up to n), divide by 2 (counting down to a small number), ...
Can we practice switching through the different kinds of local procedure bindings?
Sure. We'll do that as part of the sample quiz questions.
Do turtles always start at (0,0), facing to the right?
If the turtle is created with
turtle-new, then yes.If the turtle is created with
turtle-clone, then no. (The goal inturtle-cloneis to maintain image, position, and direction.)
When we use turtle-turn!, what direction does it turn?
Clockwise (to the right from the direction facing, assuming that you are turning a positive amount).
Also, the opposite of what experience would lead you to expect, since everything tends to be upside-down in GIMP coordinates.
Angles are "upside-down" from what you expect. 90 degrees is "down", not "up".
Can you turn a negative amount?
Yes. That's counter-clockwise (or left)
Write a series of instructions to draw a hexagon with side-length 20.
Write a series of instructions to draw a five-pointed star.
"It looks like California, but with sharp edges."
(define canvas (image-show (image-new 200 200)))
(define trop (turtle-new canvas))
(turtle-teleport! trop 100 100)
(for-each
(lambda (x)
(turtle-forward! trop (* 10 x))
(turtle-turn! trop (* 45 x)))
(cdr (iota 7)))
(define canvas (image-show (image-new 200 200)))
(define trop (turtle-new canvas))
(turtle-teleport! trop 100 100)
(repeat 8
(lambda ()
(turtle-forward! trop 10)
(turtle-turn! trop 45)))
(define tally-odds
(lambda (lst)
(tally-odds-helper 0 lst)))
(define tally-odds-helper
(lambda (tally remaining)
(cond
([null? remaining]
tally)
[(odd? (car remaining))
(tally-odds-helper (+ 1 tally) (cdr remaining))]
[else
(tally-odds-helper tally (cdr remaining))])))
"Just add a letrec before the lambda and shove the definition of tally-odds-helper into that letrec."
(define tally-odds
(letrec ([tally-odds-helper
(lambda (tally remaining)
(cond
([null? remaining]
tally)
[(odd? (car remaining))
(tally-odds-helper (+ 1 tally) (cdr remaining))]
[else
(tally-odds-helper tally (cdr remaining))]))])
(lambda (lst)
(tally-odds-helper 0 lst))))
(define tally-odds
(lambda (lst)
(tally-odds-helper 0 lst)))
(define tally-odds-helper
(lambda (tally remaining)
(cond
([null? remaining]
tally)
[(odd? (car remaining))
(tally-odds-helper (+ 1 tally) (cdr remaining))]
[else
(tally-odds-helper tally (cdr remaining))])))
let and the name"."Copy and paste the body."
(define tally-odds
(lambda (lst)
(let tally-odds-helper ([tally 0]
[remaining lst])
(cond
([null? remaining]
tally)
[(odd? (car remaining))
(tally-odds-helper (+ 1 tally) (cdr remaining))]
[else
(tally-odds-helper tally (cdr remaining))]))))
It's weird. There's no explicit call. You learn to deal with this for
named let.
Write a generalized tally pattern that we can easily turn into something that can tally any type of value.
The aforementioned tally-odds will fail miserably if the list contains "a" or others "odd to ask whether they are odd" values. Fix the code.
(define iota
(lambda (n)
(letrec ([kernel (lambda (so-far i)
(if (= i 0)
so-far
(kernel (cons i so-far) (- i 1))))])
(kernel null n))))
Consider the following procedure
(define r
(lambda (lst)
(let kernel ([a null]
[b lst])
(display (list 'kernel a b)) (newline)
(if (null? b)
a
(kernel (cons (car b) a) (cdr b))))))
What is the output when we do (r (iota 5))?
(kernel '() '(0 1 2 3 4))
(kernel '(0) '(1 2 3 4))
(kernel '(1 0) '(2 3 4))
(kernel '(2 1 0) '(3 4))
(kernel '(3 2 1 0) '(4))
(kernel '(4 3 2 1 0) '())
(define r
(lambda (lst)
(let kernel ([a null]
[b null]
[remaining lst])
(display (list 'kernel a b remaining)) (newline)
(if (null? remaining)
(list a b)
(kernel b (cons (car remaining) a) (cdr remaining))))))
What is the output for (r (iota 5))?
How would you describe what this procedure does?
Why would anyone ever want to use this procedure?
(kernel '() '() '(0 1 2 3 4))
(kernel '() '(0) '(1 2 3 4))
(kernel '(0) '(1) '(2 3 4))
(kernel '(1) '(2 0) '(3 4))
(kernel '(2 0) '(3 1) '(4))
(kernel '(3 1) '(4 2 0) '())
A claim: This separates the values at even and odd positions, giving you back in .
(r (list "a" "b" q" 3 1 2))