/* C version of the procedure `called' */ #include int called() { static int count = 0; int incr = 0; incr++; count = count + incr; return(count); } int main() { cout << endl << "count: " << called() << endl; cout << "count: " << called() << endl; cout << "count: " << called() << endl; cout << "count: " << called() << endl; } ;; Scheme version of the procedure `called' (define called (let ( (count 0) ) ;; private (to the procedure `called') ;; declaration of count defined only once prior to ;; any calls made to procedure `called' (lambda () (let ( (incr 0) ) ;; declaration of incr (redefined for each call) (set! incr (+ incr 1)) (set! count (+ count incr)) count) ))) // A C++ class with instances that have a similar semantics (not quite // the same, see below) #include class CallCounter { private: int count; public: counter () { // constructor to initialize count count = 0; } int called() { int incr = 0; incr++; count = count + incr; return(count); } }; int main () { CallCounter Ctr; // creating an instance of CallCounter cout << Ctr.called() << endl; cout << Ctr.called() << endl; cout << Ctr.called() << endl; cout << Ctr.called() << endl; } ;; A procedure that is semantically equivalent to the class CallCounter ;; (except for the error message) would be as follows: (define make-CallCounter (lambda () (let ( (count 0) ) (lambda (message) (case message ((called) (lambda () (set! count (+ count 1)) count)) (else (error "Invalid message to CallCounter" message)) ))))) (define Ctr (make-CallCounter)) ;; creating an instance of CallCounter ;; named Ctr ;; Notice that I didn't use the variable `incr' at all ;; but they are still equivalent!! The code doesn't have to perform ;; the same actions to be equivalent. Only the observable ;; behavior has to be the same for them to be equivalent. ;; To send messages to Ctr, at the Scheme prompt type: > ((Ctr 'called)) 1 > ((Ctr 'called)) 2 > ((Ctr 'called)) 3 > ((Ctr 'called)) 4