; Let's try to write a recursive function ; that reverses the elements of a list ; this one doesn't do it correctly! (define (reverse1 lst) (if (empty? lst) '() (cons (reverse1 (cdr lst)) (car lst)))) ; nor does this one!! (define (reverse2 lst) (if (null? lst) '() (list (reverse2 (cdr lst)) (car lst)))) ; this one works but it is sloppy (define (reverse3 lst) (if (null? lst) '() (append (reverse3 (cdr lst)) (list (car lst))))) ; a more efficient implementation is a tail recursive one (define (rev lst res) (if (null? lst) res (rev (cdr lst) (cons (car lst) res)))) (define (reverse4 lst) (rev lst '())) ; finally, use a "named" let, that binds the name 'rev' to a ; nested procedure that tail recurses with new let bindings (define (reverse5 lst) (let rev ((x lst) (res '())) (if (null? x) res (rev (cdr x) (cons (car x) res))))) (define (reverse6 lst) (foldl cons '() lst)) ; evaluate each and check the result ;(reverse1 '(1 2 3 4 5)) ;(reverse2 '(1 2 3 4 5)) ;(reverse3 '(1 2 3 4 5)) ;(reverse4 '(1 2 3 4 5)) ;(reverse5 '(1 2 3 4 5)) ;(reverse6 '(1 2 3 4 5)) (define mfoldl (lambda (fun init lst) (if (empty? lst) init (mfoldl fun (fun (car lst) init) (cdr lst))))) (define mmap (lambda (f lst) (if (empty? lst) '() (append (list (f (car lst))) (mmap f (cdr lst)))))) (define mmap (lambda (f lst res) (if (empty? lst) (reverse6 res) (mmap f (cdr lst) (cons (f (car lst)) res))))) (define (square x) (* x x))