CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (copy l)
(match `l` ; (list 1 2 3)
[(list) `(list)`]
[(cons h l)
; h = 1
; l = (list 2 3)
(define result (copy l))
; result = (list 2 3)
`(cons h result)`
; output = (list 1 2 3)
]
))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (copy l)
(match `l` ; (list 1 2 3)
[(list) `(list)`]
[(cons h l)
; h = 1
; l = (list 2 3)
(define result (copy l))
; result = (list 2 3)
`(cons h result)`
; output = (list 1 2 3)
]
))
(define (copy-foldr l)
(foldr
; step
(lambda (h result)
`(cons h result)`
)
; base-case
`(list)`
; list we are iterating over
`l`
)
)
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (reverse-copy l)
(`foldr`
; step
(lambda (h result)
(cons h result)
)
; base-case
(list)
; list we are iterating over
l
)
)
foldr and foldl is the traversal ordercons adds to the l-h-s)cons)CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (cons-right x l)
...
)
; x = 4
; l = (list 1 2 3)
; output = (list 1 2 3 4)
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (cons-right x l)
; x = 4
; l = (list 1 2 3)
(match l
[(list) (list x)]
[(cons h l)
; h = 1
; l = (list 2 3)
(define result (cons-right x l))
; result = (list 2 3 4)
(cons h result)
; output = (list 1 2 3 4)
]
))
(define (reverse-slow l)
(match l ; (list 1 2 3)
[(list) (list)]
[(cons h l)
; h = 1
; l = (list 2 3)
(define result (reverse-slow l))
; result = (list 3 2)
(cons-right h result)
]
)
)
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
cons-right is that it needs to traverse the whole listcons-right and reverse-slow with either foldl or with foldr?CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
Implement function (reverse l) that reverses a list.
(check-equal? (list 4 3 2 1) (reverse (list 1 2 3 4)))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
Implement function (reverse l) that reverses a list.
(check-equal? (list 4 3 2 1) (reverse (list 1 2 3 4)))
(define (reverse l)
(define (rev accum l)
(match l
[(list) accum]
[(cons h l) (rev (cons h accum) l)]))
(rev l (list)))
accum as a "loop variable", that is, a variable that we update at each iteration.rev is that recursing can be thought of as "calling" the next iteration of the loop where we update the loop variables (i.e., accum and l with their new respective values)CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
>>> " + ".join(["x", "y", "z"])
"x + y + z"
>>> " + ".join([])
""
>>> " + ".join(["x"])
"x"
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(require rackunit)
(check-equal? (join ", " '("x" "y" "z")) "x, y, z")
(check-equal? (join ", " '()) "")
(check-equal? (join ", " '("x")) "x")
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (join-suffix sep l)
(match l
[(list) ""]
[(list x) x]
[(cons h l)
(string-append h sep (join-suffix sep l))
]
)
)
(list x) to identify the last elementfolds.CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (join-prefix sep l)
(match l
[(list) ""]
[(cons h l)
(define (join-iter l)
(match l
[(list) ""]
[(cons h l)
; h = "b"
; l = (list "c")
(string-append sep h
(join-iter l))
; output = ", b, c"
]
)
)
(string-append h (join-iter l))]))
join-iter with foldr!CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (join sep l)
(define (join-iter accum l)
(match l
[(list) accum]
[(cons h l)
(join-iter
(string-append accum sep h)
l)]))
(match l
[(list) ""]
[(cons h l) (join-iter h l)]))
accum to build the list,
rather than handling the result of recursionCS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
def join(sep, l):
if l == []:
return ""
accum = l[0]
l = l[1:]
for x in l:
accum = accum + sep + x
return accum
>>> l = ["x", "y", "z"]
>>> join(", ", l)
'x, y, z'
(define (join sep l)
(define (join-iter accum l)
(match l
[(list) accum]
[(cons h l)
(join-iter
(string-append accum sep h)
l)]))
(match l
[(list) ""]
[(cons h l) (join-iter h l)]))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
; Example 1
(define (reverse l)
* (define (rev accum l)
* (match l
* [(list) accum]
* [(cons h l) (rev (cons h accum) l)]))
(rev l (list)))
; Example 2
(define (join sep l)
* (define (join-iter accum l)
* (match l
* [(list) accum]
* [(cons h l)
* (join-iter
* (string-append accum sep h)
* l)]))
(match l
[(list) ""]
[(cons h l) (join-iter h l)]))
(define (rec base-case l)
(match l
[(list) base-case]
[(cons h l)
(rec (step h accum) l)]))
(cons h accum)
(step h accum)
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (rec base-case l)
(match l
[(list) base-case]
[(cons h l)
(rec (step h accum) l)]))
(define (foldl step base-case l)
(match l
[(list) base-case]
[(cons h l)
(foldl (step h accum) l)]))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (join sep l)
(define (join-iter accum l)
(match l
[(list) accum]
[(cons h l)
(join-iter
(string-append accum sep h)
l)]))
(match l
[(list) ""]
[(cons h l) (join-iter h l)]))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (join sep l)
(define (join-iter accum l)
(match l
[(list) accum]
[(cons h l)
(join-iter
(string-append accum sep h)
l)]))
(match l
[(list) ""]
[(cons h l) (join-iter h l)]))
(define (join sep l)
(match l
[(list) ""]
[(cons h l)
* (define (step elem accum)
* (string-append accum sep elem))
* (foldl step h l)]))
Python version suggested by Dakai Tzou:
from functools import reduce
def join(l, sep):
if l == []:
return l
def step(elem, accum):
return elem + sep + accum
return reduce(step, l[1:], l[0])
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (reverse l)
(define (rev accum l)
(match l
[(list) accum]
[(cons h l) (rev (cons h accum) l)]))
(rev l (list)))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
(define (reverse l)
(define (rev accum l)
(match l
[(list) accum]
[(cons h l) (rev (cons h accum) l)]))
(rev l (list)))
(define (reverse l)
(define (on-elem elem accum)
(cons elem accum))
(foldl on-elem (list) l))
or
(define (reverse l)
(foldl cons (list) l))
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
Write a function
(to-string l)that takes a list of numbers and renders them as[n1, n2, ...]. Example,(list-to-string '(1 2 3))should output[1, 2, 3]. Functionnumber->stringconverts a number into a string
CS450 ☽ foldl, looping first-to-last; tail-recursion ☽ Lecture 08 ☽ Tiago Cogumbreiro
Write a function
(to-string l)that takes a list of numbers and renders them as[n1, n2, ...]. Example,(list-to-string '(1 2 3))should output[1, 2, 3]. Functionnumber->stringconverts a number into a string
(define (to-string l)
(string-append
"["
(join ", " (map number->string l))
"]"))
join can use the list)1, 2, 3