;; 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-beginner-reader.ss" "lang")((modname lect05) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) ; What is the type of: symbol=? : symbol symbol -> boolean ; What is the type of: and : boolean boolean -> boolean (*) ; What is the type of: if : boolean α α -> α (*) ; (*) short-circuits! -- technically, not a function but a 'special form'. ; // Java, wishful thinking: ; double avg = if (n==0) use 1.0 else use (tot/n); ; // Java actual code: (but worry about precedence?) ; double avg = (n==0) ? 1.0 : (tot/n); ; α is a "type variable" -- it can stand for number, string, whatever. ; We use it to say that `if`s 2nd and 3rd args can be any type, but ; they have to be the *same* type (and, that will be the return-type, too). ; ; Java also has type-variabes, or "generics": ; here we tell Java that the return-type will ; be the same type as the second argument: ; T foo( int a, T b) {...} #| The Design Recipe (take 1 -- primitive types only) ------- per function: 4. tests 5. stub : signature, header, description, stub-body 7. complete the body-expression 8. watch your tests pass |# ; Task: `turn`, for changing a stop-light. ; ...wait, what data type to use? ; Data Definition: ; A slc ("stoplight color") is one of: ; - 'red ; - 'yellow ; - 'green ; - 'flashing-yellow ; - 'flashing-red (check-expect (turn 'red) 'green) (check-expect (turn 'green) 'yellow) (check-expect (turn 'yellow) 'red) (check-expect (turn 'flashing-red) 'flashing-red) (check-expect (turn 'flashing-yellow) 'flashing-yellow) ; turn : slc -> slc ; return the next color for a stop-light. ; (define (turn curr-color) (cond [(symbol=? curr-color 'red) 'green] [(symbol=? curr-color 'yellow) 'red] [(symbol=? curr-color 'green) 'yellow] [(symbol=? curr-color 'flashing-yellow) 'flashing-yellow] [(symbol=? curr-color 'flashing-red) 'flashing-red] )) #| We actually just did several more steps of the design-recipe. 1. Choose data definition 2. Give some examples of the data 3. Template: a. If handling a union type, include a cond w/ one branch per option. Note that if we write five more functions involving stoplight-colors, we only need do steps 1-3 once. (And we'll copy/paste 3a over and over, for each functions.) |# ; Step 3, TEMPLATE, for the streetlight-color data type: ; ; func-for-slc : slc -> ??? ; (define chr (cond [(symbol=? a-slc 'red) ...] [(symbol=? a-slc 'yellow) ...] [(symbol=? a-slc 'green) ...] [(symbol=? a-slc 'flashing-yellow) ...] [(symbol=? a-slc 'flashing-red) ...])) ; Task: Write a function to return the tax-due, given taxable-income. ; (for single tax-payers; we'll stop after 3 brackets) ; ($9075 => 10%; $36900 => 15%; else 25% ) ; http://www.forbes.com/sites/kellyphillipserb/2013/10/31/irs-announces-2014-tax-brackets-standard-deduction-amounts-and-more/ ; TODO: Step 4: develop test cases: (check-expect (tax 0) 0) (check-expect (tax 10) 1) (check-expect (tax 9075) 907.50) (check-expect (tax 9076) 907.65) (check-expect (tax 36900) (+ (* 0.10 9075) (* 0.15 (- 36900 9075))) ) (check-expect (tax 46900) (+ (* 0.10 9075) (* 0.15 (- 36900 9075)) (* 0.25 10000))) ; a taxable-income is either: ; - a number <= 9075, OR it's ; - a number > 9075 and is <= 36900, Or it's ; - a number > 36900. ; tax : number -> number ; return the tax-due, given taxable-income. ; (for single tax-payers; we'll stop after 4 brackets) (define (tax income) (cond [(<= income 9075) (* 0.10 income)] [(<= income 36900) (+ (* 0.10 9075) (* 0.15 (- income 9075)))] [else (let* {[tier2 (- 36900 9075)] [excess (- income 36900)]} (+ (* 0.10 9075) (* 0.15 tier2) (* 0.25 excess)))])) ; Update: ; a taxable-income-entry is either: ; - 'exempt (a claim that income is exempt-- tax-treaty?), OR it's ; - #f (represents no taxes filed!), OR it's ; - a number <= 9075, OR it's ; - a number > 9075 and is <= 36900, Or it's ; - a number > 36900. ; (**) or, collapse the last three cases, and just say it's a "taxable-income" ; as previously defined? (define (func-for-taxable-income-entry a-tie) (cond [(symbol? a-tie) ...] [(boolean? a-tie) ...] [(<= a-tie 9075) ...] [.. ..] [.. ..]) ; DESIGN QUESTION: ; Should we make `tax2` call `tax` as a helper? ; I'd say, Answer: depending on our data-def'n: ; if we included 5 branches in 'taxable-income-entry', we should have 5 branches. ; Otherwise three. ; But that just begs the question: what is the right data-def'n -- ; should it have 'exempt,#f,number or should it have 5 branches? ; I tend towards the former.