Lecture 9, July 7

The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.

Higher order programming

The following five functions are important to know: I can guarentee that these functions will appear on the next quiz. Sometimes I ask people their types. Sometimes I ask people to evaluate expressions that include them. A few times I've asked people to write their own definitions of these functions.

In class exercise

#lang typed/racket

(require "../include/uchicago151.rkt")

;Write squares to give the list of the first squares
;    (squares 5) => '(0 1 4 9 16)
(: squares : Nonnegative-Integer -> (Listof Nonnegative-Integer))
(define (squares n)
  (build-list n sqr))

;Write odd-list to give the list of the first odd numbers
;    (odd-list 5) => '(1 3 5 7 9)
(: odd-list : Nonnegative-Integer -> (Listof Nonnegative-Integer))
(define (odd-list n)
  (local
    {(: odd : Nonnegative-Integer -> Nonnegative-Integer)
     (define (odd n)
       (add1 (* 2 n)))}
    (build-list n odd)))

;Write magnitudes to compute the magnitudes of a list of vectors
;    (magnitudes (list (Point 3 4) (Point 0 3) (Point 5 12)))
;        => (list 5 3 13)
(define-struct Point
  ([x : Real]
   [y : Real]))
(: magnitudes : (Listof Point) -> (Listof Number))
(define (magnitudes l)
  (local
    {(: mag : Point -> Number)
     (define (mag p)
       (sqrt (+ (sqr (Point-x p)) (sqr (Point-y p)))))}
    (map mag l)))

;Write scale that takes a list of Points and a Real and scales the 
;    points by that number
;    (scale (list (Point 3 5) (Point 7 2) (Point 6 0)) 2)
;        => (list (Point 6 10) (Point 14 4) (Point 12 0))
(: scale : (Listof Point) Real -> (Listof Point))
(define (scale l n)
  (local
    {(: scale-pt : Point -> Point)
     (define (scale-pt p)
       (Point (* n (Point-x p))
              (* n (Point-y p))))}
    (map scale-pt l)))

;Write scale/xy that takes a list of Points and two Reals and scales the 
;    points x and y coordinates by those numbers
;    (scale (list (Point 3 5) (Point 7 2) (Point 6 0)) 2 3)
;        => (list (Point 6 15) (Point 14 6) (Point 12 0))
(: scale/xy : (Listof Point) Real Real -> (Listof Point))
(define (scale/xy l nx ny)
  (local
    {(: scale-pt : Point -> Point)
     (define (scale-pt p)
       (Point (* nx (Point-x p))
              (* ny (Point-y p))))}
    (map scale-pt l)))

;Write odds to remove all the evens from a list
;    (odds '(1 4 3 6 8 7)) => '(1 3 7)
(: odds : (Listof Integer) -> (Listof Integer))
(define (odds l)
  (filter odd? l))

;Write gt-10 to keep only the numbers greater than 10
;    (gt-10 '(15 3 -20 11)) => '(15 11)
(: gt-10 : (Listof Integer) -> (Listof Integer))
(define (gt-10 l)
  (local
    {(: t : Integer -> Boolean)
     (define (t x)
       (> x 10))}
    (filter t l)))

;Write exact-squares to keep only the numbers that are exact squares
;    - the numbers with exact integer square roots
;    (exact-squares '(1 4 5 24 16)) => '(1 4 16)
(: exact-squares : (Listof Number) -> (Listof Number))
(define (exact-squares l)
  (local
    {(: exact-square : Number -> Boolean)
     (define (exact-square n)
       (exact-integer? (sqrt n)))}
    (filter exact-integer? l)))

;Write sum to add a list of numbers
;    (sum '(1 2 3)) => 6
(: sum : (Listof Number) -> Number)
(define (sum l)
  (foldr + 0 l))

;Write append-strings to append a list of strings together into one string
;    (append-strings '("Hi" "Cat" "Dog")) => "HiCatDog"
(: append-strings : (Listof String) -> String)
(define (append-strings l)
  (foldr string-append "" l))

;Last lecture I did map and filter as examples
;Do build-list, foldr, and foldl now.
(: build-list : (All (A) (Nonnegative-Integer (Nonnegative-Integer -> A) -> (Listof A))))
(define (build-list n f)
  (local
    {(: helper : Nonnegative-Integer -> (Listof A))
     (define (helper i)
       (cond
         [(= i n) empty]
         [else (cons (f i) (helper (add1 i)))]))}
    (helper 0)))

(: foldr : (All (A B) (A B -> B) B (Listof A) -> B))
(define (foldr f i l)
  (cond
    [(empty? l) i]
    [else (f (first l) (foldr f i (rest l)))]))

(: foldl : (All (A B) (A B -> B) B (Listof A) -> B))
(define (foldl f i l)
  (cond
    [(empty? l) i]
    [else (foldl f (f (first l) i) (rest l))]))