In the previous lab, one of our examples was the following:
Develop
; factorial-count! : natnum -> natnum ; Purpose: Returns the factorial of its argument. ; Effects: Increments factorial-counter. ; Examples: ; #| ; > factorial-counter ; 0 ; > (factorial-count! 3) ; 6 ; > factorial-counter ; 1 ; > (factorial-count! 5) ; 120 ; > factorial-counter ; 2
To solve it, you should have written something like
(define factorial-count 0) (define (factorial-count! n) (local [(define (factorial n) (cond [(zero? n) 1] [else (* n (factorial (sub1 n)))]))] (begin (set! factorial-count (add1 factorial-count)) (factorial n))))
This technique of keeping track of some information about the function calls is fairly common. However, we would like to hide the counter factorial-count locally inside the function factorial-count!, so that nobody else can change it.
Simply adding a local definition is easy enough, but there are two big problems if the counter isn't global:
To do as a class: Develop
factorial-count! : ('init or 'count or natnum) -> (void or natnum)The input is simply a "message" indicating one of the possible actions of the function:
Here's another example. Let's model a very simple bank account. All we will remember about this account is the current balance. We need at least the ability to add and subtract from this balance for deposits and withdrawals. For withdrawals, we want to model the possibility of rejecting withdrawals when there's not enough in the account.
For deposits and withdrawals, we need to also provide an amount. Here's one way how to do this. When we give an account a message such as 'deposit, the account will return a function which takes the amount to deposit and then does the deposit. (Note: We could provide the amount as part of the message, but we're taking you on a different path.)
To do:
Develop account to model a single account. The initial balance should be zero. It takes three messages: 'deposit, 'withdraw, or 'balance, corresponding to the obvious meanings. An unsuccessful withdrawal returns 'insufficient-balance and does not alter the balance. This should be identical in structure to the previous example.
With a slight modification, define bank which is simply a function of no arguments that creates a new account with a separate balance per account.
To do: With whatever time remains, add features to your account or bank examples, making them more realistic models. Be creative! Some suggestions:
An account in this last example is very similar to an object in object-oriented programming. The functions for handling deposits and withdrawals are called methods, the balance is called a field. Each account "object" is called an instance of all-the-accounts (we don't have a good equivalent in this example), and we have a mechanism (the bank) for creating instances.
Object-oriented programming basically looks at all values being objects of this form -- something with methods that can use and modify local fields. There are other concepts in object-oriented programming, such as classes and inheritance, that we'll leave to Comp 212 to introduce.