UNB/ CS/ David Bremner/ teaching/ cs4613/ lectures/ lecture06/ state4.rkt
#lang racket
(require [only-in plait test test/exn error print-only-errors])

(define mk-o-static
  (let ([counter 0]) ;; outside constructor
    (lambda (amnt)
      (begin
        (set! counter (+ 1 counter))
        (lambda (m)
          (case m
            [(inc) (lambda (n) (set! amnt (+ amnt n)))]
            [(dec) (lambda (n) (set! amnt (- amnt n)))]
            [(get) (lambda () amnt)]
            [(count) (lambda () counter)]))))))

(define-syntax snd
  (syntax-rules ()
    [(_ obj selector args ...)
     ((obj (quote selector)) args ...)]))

(test (let ([o (mk-o-static 1000)])
        (snd o count))
      1)
(test (let ([o (mk-o-static 0)])
        (snd o count))
      2)
(test (let ([o1 (mk-o-static 3)]
            [o2 (mk-o-static 3)])
        (begin (snd o1 inc 2) (snd o1 inc 2)
               (list (snd o1 get) (snd o2 get))))
      '(7 3))