This class will be recorded! Its use is limited to members of the class. Please do not share with others.
Approximate overview
Attend (or watch recording within a day or so) and send a one-paragraph reflection asap afterwards.
Only those activities I list count.
Mini Projects
Readings
Quizzes
Other
I’m going to take a bunch of questions at first, answer the short ones, and put the long ones on hold. Then I’ll answer the long ones and we’ll do it all over again.
I forgot to ask for more time on my SoLAs before the deadline. Can I still get more time?
Yes. You can ask out loud now or just chat me in Teams. 30, 40, 50, or 60.
I have an accommodation that gives me a particular extension on the SoLAs. Can I ask for more than that on the SoLAs.
Of course. Just let me know how long you want.
Will you go over vector-swap-neighbors!?
Sure
Write a procedure, (vector-swap-neighbors! vec) that takes an even-length vector as a parameter and swaps the neighboring elements (those at indices 0 and 1, those at indices 2 and 3, etc.).
(define vector-swap-neighbors!
(lambda (vec)
(let ([len (vector-length vec)])
(letrec ([helper
(lambda (pos)
(when (< pos len)
(let ([val0 (vector-ref vec pos)]
[val1 (vector-ref vec (+ 1 pos))])
(vector-set! vec (+ pos 1) val0)
(vector-set! vec pos val1)
(helper (+ pos 2)))))])
(helper 0)))))
> (define vec2 (vector 'a 'b 'c 'd))
> (vector-swap-neighbors! vec2)
> vec2
'#(b a d c)
> (define vec3 (list->vector (range 20)))
> vec3
'#(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
> (vector-swap-neighbors! vec3)
> vec3
'#(1 0 3 2 5 4 7 6 9 8 11 10 13 12 15 14 17 16 19 18)
Here’s a trace of an earlier incorrect version.
; (vector-swap-neighbors! (vector 'a 'b 'c 'd))
; --> (helper 0)
; --> ; val0 'a val1 'b
; --> ; vector is now (vector 'b 'a 'c 'd)
; --> (helper 2)
; --> ; val0 is 'b
When should we use when?
When writing recursive procedures in a world with side effects, we often need to sequence operations (do this, then this, then recurse).
ifdoesn’t give us multiple consequents or multiple alternates.
We have a few choices. We could use
cond
(cond
[(< pos len)
(vector-set! vec (+ pos 1) val0)
(vector-set! vec pos val1)
(helper (+ pos 2))]
[else
vec])
But I don’t like to return vectors from ! procedures.
So I guess I could write
(cond
[(< pos len)
(vector-set! vec (+ pos 1) val0)
(vector-set! vec pos val1)
(helper (+ pos 2))])
whenis just a shorter version of thecondI just wrote. It saved me two whole square brackets. But I find them easier to read.
If the guard in the
whendoes not hold, thewhendoes nothing and has no value (void).
Don’t use
whenif you want an alternate. Usecond. Feel free to skipwhenaltogether.
Could you discuss the mechanics of the vector recursion?
Sure.
In most vector-recursive procedures, we want to step through the indices. From 0 up to the last index. Or from the last index down to 0.
From 0 up is the most common.
Essentially, we’re doing numeric recursion with vector indices from 0 up to
(- (vector-length vec) 1).
posis the term I use for the index. “position”.
If we’re counting up from 0, we want to initialize the recursive process at zero.
(let ([helper
(lambda (pos)
...)])
(helper 0))
Describe or diagram the layout of memory for lists and vectors/arrays.
Consider the following pair structure represented in ASCII art.
(cons "a" (cons * (cons "e" (cons "f" null))))
+---+---+ +---+---+ +---+---+ +---+---+
| * | *--->| * | *--->| * | *--->| * | / |
+-|-+---+ +-|-+---+ +-|-+---+ +-|-+---+
v | v v
"a" | "e" "f"
v
(cons * (cons null (cons * null)
+---+---+ +---+---+ +---+---+
| * | *--->| / | *--->| * | / |
+-|-+---+ +---+---+ + | +---+
v v
(cons * null) (cons "c" "d")
+---+---+ +---+---+
| * | / | | * | * |
+-|-+---+ +-|-+-|-+
v v v
(cons null "b") "c" "d"
+---+---+
| / | | |
+---+-|-+
v
"b"
(cons "a"
(cons '...
(cons "e"
(cons "f"
null))))
(cons "a"
(cons (cons (cons (cons null "b")
null)
(cons null
(cons (cons "c" "d")
null)))
(cons "e"
(cons "f"
null))))
Wasn’t that fun?
'("a" ("b" "c" . "d") () (("e")))
(cons "a"
(cons (cons "b"
(cons "c"
"d"))
(cons null
(cons (cons (cons "e"
null)
null)
null))))
+---+---+ +---+---+ +---+---+ +---+---+
| * | *---> | * | *---> | / | *---> | * | / |
+-|-+---+ +-|-+---+ +---+---+ +-|-+---+
v v v
"a"
hops = higher-order procedures
(define silly
(lambda (lst)
(map (lambda (x) (sqr (+ 1 x)))
(filter odd? lst))))
Strategies
Let’s consider the inner lambda first.
(lambda (x) (sqr (+ 1 x)))(o sqr "add one to")(o sqr (section + 1 <>))(define sillier
(lambda (lst)
(map (o sqr (section + 1 <>))
(filter odd? lst))))
Let’s deal with outer lambda.
(o map-thingy filter-thingy)(section filter odd? <>)(section map ugly-thing <>)(section map (o sqr (section + 1 <>)) <>)(define silliest
(o (section map (o sqr (section + 1 <>)) <>)
(section filter odd? <>)))
The diamonds represent “the input to this procedure”. (That’s one of the reasons we often go to a one-parameter procedure; it’s easier to think of just one input than many.)
Similar to the lab headers.
;; CSC 151.02 (Fall 2020, Term 2)
;; Mini-Project 5
;; Authors: YOUR NAMES HERE
;; Date: THE DATE HERE
;; Acknowledgements:
;; ACKNOWLEDGEMENTS HERE
At the top.
;; Acknowledgements:
;; * Sam helped on the broad design of the project.
;; * L's questions in class gave me a sense of how to approach
;; the question on haiku.
;; * Mai helped correct my code on the haiku.
;; * I referred to the Racket page on `andmap` at
;; <https://docs.racket-lang.org/reference/pairs.html>
In the documentation for procedures.
;;; (haiku) -> string?
;;;
;;; I found starter code on Stack Overflow at <...>.
;;; Mai helped me correct some of the problems.
I’m happy with either, with a slight preference for both.