#lang racket
(require [only-in plait test test/exn error print-only-errors])
(define (msg obj selector . args)
(apply (obj selector) args))
(define mk-num
(let ([secret (gensym)])
(lambda (init)
(let ([amount init])
(lambda (m)
(cond
[(equal? m secret) (lambda () amount)]
[(equal? m 'add)
(lambda (other)
(mk-num (+ amount (msg other secret))))]
[(equal? m 'odd?) (lambda () (odd? amount))]))))))
(define o2 (mk-num 2))
(define o3 (mk-num 3))
(define o4 (msg o2 'add o2))
(define o5 (msg o2 'add o3))
(test (msg o2 'odd?) #f)
(test (msg o3 'odd?) #t)
(test (msg o4 'odd?) #f)
(test (msg o5 'odd?) #t)