#lang racket (require [only-in plait test test/exn error print-only-errors]) (define (msg obj selector . args) (apply (obj selector) args)) (define (mt) (lambda (m) (case m [(sum) (lambda () 0)]))) (define (node v l r) (lambda (m) (case m [(sum) (lambda () (+ v (msg l 'sum) (msg r 'sum)))]))) (define (node/size v l r) (let ([parent-object (node v l r)]) (lambda (m) (case m [(size) (lambda () (+ 1 (msg l 'size) (msg r 'size)))] [else (parent-object m)])))) (define (mt/size) (let ([parent-object (mt)]) (lambda (m) (case m [(size) (lambda () 0)] [else (parent-object m)])))) (define a-tree/size (node/size 10 (node/size 5 (mt/size) (mt/size)) (node/size 15 (node/size 6 (mt/size) (mt/size)) (mt/size)))) (test (msg a-tree/size 'sum) (+ 10 5 15 6)) (test (msg a-tree/size 'size) 4)