;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-reader.ss" "lang")((modname list-intro-before) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; We will (a) move to intermediate-student language, and (b) require: (require racket/contract) (require "student-extras.rkt") ; ; This gives us `define/contract` and `define-struct/c`, where ; the contracts/types are no longer commented-out. #| Follow the design recipe (the final version!): ---- Per data type: 1. Choose datatype definition 2. Give some examples of the data 3. Template: a. If handling a union type, include a cond w/ one branch per option. b. If handling a product-type, pull out each piece (field). c. Inventory: In all cases, think about what *type* (each piece) is, and think of some functions that process that type. d. Add the natural recursive call (as appropriate) ---- Per function: 4. write test cases 5. (a-d): copy the template; complete header, purpose, contract/type; stub the "..."s. 6. Inventory with values: Consider a particular test case, and think about what *specific* *value* of each sub-expression template has. 7. complete the body 8. run tests |# #| Definition: argument: the value passed into a function parameter: a function's local variable/identifier which is initialized from the arguments (each time the function is *called*). |# #| Today's+Tomorrow's outline: 1. Design recipe (recall, v.quickly). 2. datatype def'n for: list (including the non-built-in-way) 3. processing a list: sum write: length write: contains? (return a bool) write: triple-every-even (return a *list*) write: my-max (note bad run-time) learn: let* |# ; to-model: a list of numbers. ; ; Datatype Definition: #;(define (list? val) ...) #;(define-struct/c cons ([first any/c] [rest list?])) ; interpretation: `first` tacked to the front of the list `rest`. ; '() is the empty list; there is also the named-constant `empty`, bound to it. ; Note that we could use any value we like, to represent the empty-list -- just so long ; as we can distinguish it from a cons-struct. ; Examples of data: '() (cons 17 '()) (cons 15 (cons 17 '())) (cons 13 (cons 15 (cons 17 '()))) (first (cons 13 (cons 15 (cons 17 '())))) (rest (cons 13 (cons 15 (cons 17 '())))) ; The constructor isn't *actually* `make-cons`, but instead just `cons`. ; The selectors aren't *actually* `cons-first`, but instead just `first` ; and not `cons-rest`, but instead just `rest`. ; ; There *is* a predicate `cons? : (-> any/c boolean?)`. ; Also, there is a predicate to test for the empty-list: `empty? : (-> any/c boolean?)` ;; template, for *any* function handling a list: ; (define/contract (func-for-list a-lon) (-> list? ...?) ; Return ... of `a-lon`. ...TODO...) (check-expect (sum '()) 0) (check-expect (sum (cons 3 '())) 3) (check-expect (sum (cons 4 (cons 3 '()))) 7) (check-expect (sum (cons 5 (cons 4 (cons 3 '())))) 12) (define/contract (sum a-lon) (-> list? number?) ; return the sum of the numbers in `a-lon` ...TODO...) ; inventory with values: suppose that `a-lon` stands for ; (cons 5 (cons 4 (cons 3 '()))). ; So what is (first a-lon) in this case? 5 <--- ; So what is (rest a-lon) in this case? ; (cons 4 (cons 3 '())) <--- ; So what is (sum (rest a-lon)) in this case? 7 <--- ; sub-question: what is (rest a-lon) in this case? (cons 2 (cons 4 '())) ; So what should my answer be in this case? 12 (check-expect (sum '()) 0) (check-expect (sum (cons 4 '())) 4) (check-expect (sum (cons 2 (cons 4 '()))) 6) (check-expect (sum (cons 3 (cons 2 (cons 4 '())))) 9) (check-expect (my-length '()) 0) (check-expect (my-length (cons 4 '())) 1) (check-expect (my-length (cons 2 (cons 4 '()))) 2) (check-expect (my-length (cons 99 (cons 2 (cons 4 '())))) 3) #;(define/contract (my-length a-lon) ...TODO...) (check-expect (contains? 93 '()) #false) (check-expect (contains? 3 (cons 3 '())) #true) (check-expect (contains? 93 (cons 93 '())) #true) (check-expect (contains? 93 (cons 7 '())) #false) (check-expect (contains? 93 (cons 7 (cons 93 '()))) #true) (check-expect (contains? 93 (cons 93 (cons 7 '()))) #true) (check-expect (contains? 93 (cons 3 (cons 7 '()))) #false) (check-expect (contains? 93 (cons 44 (cons 93 (cons 7 '())))) #true) (check-expect (contains? 93 (cons 44 (cons 3 (cons 7 '())))) #false) #;(define/contract (contains? target a-lon) ...TODO...) #| truth-table: inputA inputB | desired-answer ------ ------- | -------------- #false #false | #false #false #true | #true #true #false | #true #true #true | #true |# ;; further self-practice: ; index-of : list-of-number, number -> natnum ; return the index of the first occurrence of `target` in `a-lon` ; pre-condition: `target` *must* occur in the `a-lon`. ; get-at : natnum, list-of-T -> T ; Return the `i`th element of `a-lon` (0-based index) ; pre-condition: `(< i (length a-lon))` (an exception will be thrown). ; ;Challenge: ; next : T, list-of-T -> T ; Return the item in `items` that comes *after* `target` (wrapping around if needed). ; pre-condition: `target` occurs in `items` (so per force, `items` can't be empty) ; ;;; This is difficult when the target is the *last* item of the list. ;;; In that case, when recurring to '(), ;;; we need to know more than just the list -- the function also ;;; needs to be told what to return when it reaches '(). ;;; HINT: Use a helper, which gets one extra additional argument. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Functions *returning* a list: ; triple-every-even (leaving odd numbers untouched) ; (check-expect (tee '()) ...) (check-expect (tee (cons 4 '())) (cons 12 '())) (check-expect (tee (cons 7 '())) (cons 7 '())) (check-expect (tee (cons 2 (cons 4 '()))) (cons 6 (cons 12 '()))) (check-expect (tee (cons 93 (cons 2 (cons 4 '())))) (cons 93 (cons 6 (cons 12 '())))) (define/contract (tee a-lon) (-> list? ...) ; "triple-every-even" -- return another list like `a-lon`, ; but every even number is tripled (and odd numbers are unchanged). ...TODO...)