(macro make-encapsulation (lambda (body) (let ((parameters (cadr body)) (variables (caddr body)) (local-procedures (cadddr body)) (methods (car (cddddr body)))) `(lambda ,parameters (let* ,variables (letrec ,(append local-procedures methods) (let ((list-of-methods (list . ,(map (lambda (x) `(cons ',(car x) ,(car x))) methods)))) (lambda (message) (let ((method (assq message list-of-methods))) (if (null? method) (error "no such method in this encapsulation: " message) (cdr method))))))))))) (macro old-use-methods (lambda (body) `(let ,(map (lambda (x) (if (pair? x) `(,(car x) (,(cadr body) ',(cadr x))) `(,x (,(cadr body) ',x)))) (caddr body)) . ,(cdddr body)))) (macro use-methods (lambda (body) (define (clause-parser clause) (map (lambda (x) (if (pair? x) `(,(car x) (,(car clause) ',(cadr x))) `(,x (,(car clause) ',x)))) (cadr clause))) `(let ,(map-append! clause-parser (cadr body)) . ,(cddr body)))) (define (make-encapsulation-iterator encapsulation) (let ((pop! (encapsulation 'pop!)) (empty? (encapsulation 'empty?))) (lambda (function) (do () ((empty?)) (function (pop!))))))