The following definitions are for question 1 (more or less copied from the notes):
;; Program 1
(define (msg1 o m a)
((o m) a))
(define (o-constr-1 x)
(lambda (m)
(case m
[(addX) (lambda (y) (+ x y))])))
(test (msg1 (o-constr-1 5) 'addX 3) 8)
(test (msg1 (o-constr-1 2) 'addX 3) 5)
;; Program 2
(define (msg0 o m)
((o m)))
(define o-static-1
(let ([counter 0])
(lambda (amount)
(begin
(set! counter (+ 1 counter))
(lambda (m)
(case m
[(inc) (lambda (n) (set! amount (+ amount n)))]
[(dec) (lambda (n) (set! amount (- amount n)))]
[(get) (lambda () amount)]
[(count) (lambda () counter)]))))))
(test (let ([o (o-static-1 1000)])
(msg0 o 'count))
1)
(test (let ([o (o-static-1 0)])
(msg0 o 'count))
2)
;; Program 3
(define (msg/self o m a)
((o m) o a))
(define o-self-no!
(lambda (m)
(case m
[(first) (lambda (self x) (msg/self self 'second (+ x 1)))]
[(second) (lambda (self x) (+ x 1))])))
(test (msg/self o-self-no! 'first 5) 7)