On Dec 21, 2010, at 5:43 PM, Sayth Renshaw wrote:
> Do i need to define the gross function in my netpay function?
No, you don't. You've already defined it by saying
(define (gross hours)
(* hours pay-rate))
> If I have defined gross function as suggested earlier why can't my netpay
> function use it?
Because by writing
(define (netpay gross tax-rate) ...)
you've invented a NEW thing named "gross", which takes precedence over the
previously-defined thing by the same name.
> (define tax-rate 0.15)
> (define pay-rate 12)
> (define (gross hours)
> (* hours pay-rate))
>
> (define (netpay gross tax-rate)
> (- gross 0 (* gross tax-rate)))
>
>
> > (netpay (gross 20)tax-rate)
> 204
Yes, I guess this works but it's way more complicated and confusing than it
needs to be, for several reasons.
1) The definition of "netpay" doesn't need to mention "tax-rate" as a
parameter, and the call to "netpay" doesn't need to pass in "tax-rate" as an
argument; "tax-rate" has been defined globally, so it can be used inside the
function anyway (as you did with "pay-rate" in the definition of "gross").
2) You have two different things named "gross": a function that takes a number
of hours and returns a number of dollars, and a (presumably numeric) parameter
to "netpay". There's nothing illegal about this, but it tends to cause
confusion.
3) In programming, there's always a conflict between making things easier to
write and making them easier to use. "netpay" would be easier to use if I
could just give it a number of hours, e.g.
(netpay 20)
You've decided to make it harder to use by expecting the user to write
(netpay (gross 20))
In other words, the user won't get the right answer unless the user does an
extra bit of work before calling netpay.
> Indeed I know what you are referencing.
> [snipped quotes about area-of-ring from the book]
OK, I'm convinced that you "know what we are referencing," but why aren't you
DOING it?
1) Write down a contract for "netpay". In this step, don't even think about
how to solve the problem. Think ONLY about how "netpay" will be used: should
it be given a number of hours, or a number of dollars, or both, or a number of
hours and a tax rate, or a number of dollars and a tax rate, or what? What
should it return?
2) Then write down two or more examples for "netpay". Each example should be a
complete function call, with specific arguments, and be accompanied by the
"right answer" (worked out by hand or on a calculator), so you can easily tell
whether the actual answer matched what you said the answer should be. I
strongly recommend using "check-expect" for this.
"check-expect" isn't discussed in _How to Design Programs_, because it hadn't
been invented yet when that book was written, but we've all been using it for
years, and it makes your life much easier because DrRacket will check all your
test cases for you and tell you which ones passed, which ones failed, and HOW
they failed.
3) Then write a function skeleton (see my previous message).
4) Then write a function inventory (see my previous message).
5) Then fill in the body; this is the hardest part, but doing the other steps
first makes it easier.
6) Then run the test cases and see if they pass.
Here's another example of how this design recipe works. Suppose I had been
asked to write a "cube" function.
; cube : number -> number
(check-expect (cube 0) 0)
(check-expect (cube 3) 27)
(check-expect (cube -6) -216)
(check-expect (cube 2/3) 8/27)
(define (cube num)
; num a number
(* num num num))
Once all of the above is in the Definitions pane, you can hit the "Run" button
and DrRacket will check all your test cases; they should all pass.
To see what happens when a program is buggy, try changing the definition of
"cube" so it's wrong:
(define (cube num)
; num a number
(* num num 3))
and hit "Run" again. It should still pass the first two test cases, but fail
the third and fourth, and DrRacket should show you both the predicted "right
answer" and the actual answer for each failed test cases.
Take a look at http://www.picturingprograms.org/pdf , which is the first few
chapters of a more up-to-date book based on _How to Design Programs_. It
discusses (in chapter 5) this design recipe in considerable detail, including
how to use check-expect.
Stephen Bloch
[email protected]
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users