2 @code{(require 'object)}
5 This is the Macroless Object System written by Wade Humeniuk
6 (whumeniu@@datap.ca). Conceptual Tributes: @ref{Yasos}, MacScheme's
7 %object, CLOS, Lack of R4RS macros.
13 An object is an ordered association-list (by @code{eq?}) of methods
14 (procedures). Methods can be added (@code{make-method!}), deleted
15 (@code{unmake-method!}) and retrieved (@code{get-method}). Objects may
16 inherit methods from other objects. The object binds to the environment
17 it was created in, allowing closures to be used to hide private
21 A generic-method associates (in terms of @code{eq?}) object's method.
22 This allows scheme function style to be used for objects. The calling
23 scheme for using a generic method is @code{(generic-method object param1
27 A method is a procedure that exists in the object. To use a method
28 get-method must be called to look-up the method. Generic methods
29 implement the get-method functionality. Methods may be added to an
30 object associated with any scheme obj in terms of eq?
32 @item GENERIC-PREDICATE
33 A generic method that returns a boolean value for any scheme obj.
36 A object's method asscociated with a generic-predicate. Returns
40 @subsection Procedures
42 @defun make-object ancestor @dots{}
43 Returns an object. Current object implementation is a tagged vector.
44 @var{ancestor}s are optional and must be objects in terms of object?.
45 @var{ancestor}s methods are included in the object. Multiple
46 @var{ancestor}s might associate the same generic-method with a method.
47 In this case the method of the @var{ancestor} first appearing in the
48 list is the one returned by @code{get-method}.
52 Returns boolean value whether @var{obj} was created by make-object.
55 @defun make-generic-method exception-procedure
56 Returns a procedure which be associated with an object's methods. If
57 @var{exception-procedure} is specified then it is used to process
61 @defun make-generic-predicate
62 Returns a boolean procedure for any scheme object.
65 @defun make-method! object generic-method method
66 Associates @var{method} to the @var{generic-method} in the object. The
67 @var{method} overrides any previous association with the
68 @var{generic-method} within the object. Using @code{unmake-method!}
69 will restore the object's previous association with the
70 @var{generic-method}. @var{method} must be a procedure.
73 @defun make-predicate! object generic-preciate
74 Makes a predicate method associated with the @var{generic-predicate}.
77 @defun unmake-method! object generic-method
78 Removes an object's association with a @var{generic-method} .
81 @defun get-method object generic-method
82 Returns the object's method associated (if any) with the
83 @var{generic-method}. If no associated method exists an error is
93 (define instantiate (make-generic-method))
95 (define (make-instance-object . ancestors)
96 (define self (apply make-object
97 (map (lambda (obj) (instantiate obj)) ancestors)))
98 (make-method! self instantiate (lambda (self) self))
101 (define who (make-generic-method))
102 (define imigrate! (make-generic-method))
103 (define emigrate! (make-generic-method))
104 (define describe (make-generic-method))
105 (define name (make-generic-method))
106 (define address (make-generic-method))
107 (define members (make-generic-method))
111 (define self (make-instance-object))
112 (define population '())
113 (make-method! self imigrate!
115 (if (not (eq? new-person self))
116 (set! population (cons new-person population)))))
117 (make-method! self emigrate!
119 (if (not (eq? person self))
121 (comlist:remove-if (lambda (member)
124 (make-method! self describe
126 (map (lambda (person) (describe person)) population)))
127 (make-method! self who
128 (lambda (self) (map (lambda (person) (name person))
130 (make-method! self members (lambda (self) population))
133 (define (make-person %name %address)
134 (define self (make-instance-object society))
135 (make-method! self name (lambda (self) %name))
136 (make-method! self address (lambda (self) %address))
137 (make-method! self who (lambda (self) (name self)))
138 (make-method! self instantiate
140 (make-person (string-append (name self) "-son-of")
142 (make-method! self describe
143 (lambda (self) (list (name self) (address self))))
148 @subsubsection Inverter Documentation
151 <inverter>::(<number> <description>)
155 <inverter>::value @result{} <number>::value
156 <inverter>::set-value! @result{} <number>::set-value!
157 <inverter>::describe @result{} <description>::describe
160 <inverter>::inverter?
163 @subsubsection Number Documention
178 @subsubsection Inverter code
183 (define value (make-generic-method (lambda (val) val)))
184 (define set-value! (make-generic-method))
185 (define invert (make-generic-method
189 (error "Method not supported:" val)))))
190 (define noop (make-generic-method))
191 (define inverter? (make-generic-predicate))
192 (define describe (make-generic-method))
193 (define help (make-generic-method))
195 (define (make-number x)
196 (define self (make-object))
197 (make-method! self value (lambda (this) x))
198 (make-method! self set-value!
199 (lambda (this new-value) (set! x new-value)))
202 (define (make-description str)
203 (define self (make-object))
204 (make-method! self describe (lambda (this) str))
205 (make-method! self help (lambda (this) "Help not available"))
208 (define (make-inverter)
209 (let* ((self (make-object
211 (make-description "A number which can be inverted")))
212 (<value> (get-method self value)))
213 (make-method! self invert (lambda (self) (/ 1 (<value> self))))
214 (make-predicate! self inverter?)
215 (unmake-method! self help)
216 (make-method! self help
218 (display "Inverter Methods:") (newline)
219 (display " (value inverter) ==> n") (newline)))
224 (define invert! (make-generic-method))
226 (define x (make-inverter))
228 (make-method! x invert! (lambda (x) (set-value! x (/ 1 (value x)))))
230 (value x) @result{} 1
231 (set-value! x 33) @result{} undefined
232 (invert! x) @result{} undefined
233 (value x) @result{} 1/33
235 (unmake-method! x invert!) @result{} undefined
237 (invert! x) @error{} ERROR: Method not supported: x