source: project/wiki/eggref/4/protobj @ 15401

Last change on this file since 15401 was 15401, checked in by svnwiki, 11 years ago

Changes applied for Anonymous coward (98.210.132.177) through svnwiki:

fix typos

File size: 8.5 KB
Line 
1[[tags: egg]]
2
3== protobj
4
5[[toc:]]
6
7=== Description
8
9Prototype-Delegation Object Model in Scheme
10
11=== Author
12
13Neil van Dyke
14
15=== Requirements
16
17[[syntax-case]]
18
19=== Documentation
20
21This extension uses the {{syntax-case}} macro-/module-system. To use
22the definitions described in this document import its bindings by
23evaluating the {{(import protobj)}} form in the current scope.
24
25Protobj is a Scheme library that implements a simple prototype-delegation
26object model, somewhat similar to that of [Self], and also related to
27[SLIB-Object] and [OScheme].  Protobj was written mainly as a
28{{syntax-rules}} learning exercise, but also because people ask about
29prototype object models for Scheme from time to time.  Like most object
30systems, it should be regarded as an amusement.  The Protobj library defines
31both a verbose set of procedures, and terse special syntax.
32
33Protobj is based on objects with named slots that can contain
34arbitrary values.  Object have immediate slots, and single parent
35objects from which additional slots are inherited.  When setting in a
36child object a slot inherited from the parent, a new immediate slot is
37created in the child so that the parent is unaffected and the slot is
38no longer inherited.
39
40Methods are simply closures stored in slots.  When a method is
41applied, the first term of the closure is the receiver object.  Unlike
42Self, getting the contents of the slot is distinguished from
43invoking a method contained in the slot.  This distinction was made
44due to the way first-class closures are often used in Scheme.
45
46An object is cloned by invoking the {{clone}} method.  The default
47root object's {{clone}} method creates a new child object without any
48immediate slots, rather than copying any slots.  This behavior can be
49overridden to always copy certain slots, to copy immediate slots, or
50to copy all inherited slots.  An overriding {{clone}} method can be
51implemented to apply its parent's {{clone}} method to itself and then
52set certain slots in the new child appropriately.
53
54The following is a quick tour of Protobj using the terse special
55syntax.
56
57Bind {{a}} to the new object that is created by cloning the default root
58object ({{%}} is special syntax for invoking the {{clone}} method):
59
60  (define a (%))
61
62Verify that {{a}} is an object and that {{a}}'s parent is the default
63root object:
64
65  (object? a) => #t
66  (eq? (^ a) (current-root-object)) => #t
67
68Add to {{a}} a slot named {{x}} with value {{1}}:
69
70  (! a x 1)
71
72Get {{a}}'s slot {{x}}'s value:
73
74  (? a x) => 1
75
76Bind {{b}} to a clone of {{a}}:
77
78  (define b (% a))
79
80Get {{b}}'s slot {{x}}'s value, which is inherited from {{a}}:
81
82  (? b x) => 1
83
84Set {{a}}'s slot {{x}}'s value to {{42}}, and observe that {{b}}
85inherits the new value:
86
87  (! a x 42)
88  (? a x) => 42
89  (? b x) => 42
90
91Set {{b}}'s slot {{x}}'s value to {{69}}, and observe that {{a}}
92retains its own {{x}} value although {{b}}'s {{x}} value has been
93changed:
94
95  (! b x 69)
96  (? a x) => 42
97  (? b x) => 69
98
99Add to {{a}} an {{xplus}} slot containing a closure that implements a
100method of the object:
101
102  (! a xplus (lambda (self n) (+ (? self x) n)))
103
104Apply the method to the {{a}} and {{b}} objects ({{b}} inherits
105any new slots added to {{a}}):
106
107  (@ a xplus 7) => 49
108  (@ b xplus 7) => 76
109
110Observe the shorthand syntax for applying methods to an object
111multiple times, with the syntax having the value of the lastmost
112application:
113
114  (@ a (xplus 1000) (xplus 7)) => 49
115
116Bind to {{c}} an object that clones {{a}} and adds slot {{y}} with
117value {{101}}:
118
119  (define c (% a (y 101)))
120
121Get the values of both the {{x}} and {{y}} slots of {{c}}:
122
123  (? c x y) => 42 101
124
125Finally, bind {{d}} to a clone of {{a}} that overrides {{a}}'s {{x}}
126slot:
127
128  (define d (% a (x 1) (y 2) (z 3)))
129  (? d x y z) => 1 2 3
130
131The basic interface of Protobj is a set of procedures.
132
133<procedure>(object? x)</procedure>
134
135Predicate for whether or not {{x}} is a Protobj object.
136
137<procedure>(object-parent obj)</procedure>
138
139Yields the parent object of object {{obj}}.
140
141<procedure>(object-set! obj slot-symbol val)</procedure>
142
143Sets the slot identified by symbol {{slot-symbol}} in object {{obj}} to
144value {{val}}.
145
146<procedure>(object-get obj slot-symbol)</procedure>
147
148Yields the value of slot named by symbol {{slot-symbol}} in object
149{{obj}} (immediate or inherited).  If no slot of that name exists, an
150error is signaled.
151
152<procedure>(object-get obj slot-symbol noslot-thunk)</procedure>
153
154Yields the value of slot named by symbol {{slot-symbol}} in object
155{{obj}} (immediate or inherited), if any such slot exists.  If no slot
156of that name exists, then yields the value of applying closure
157{{noslot-thunk}}.
158
159<procedure>(object-apply obj slot-symbol { arg }*)
160
161Applies the method (closure) in the slot named by {{slot-symbol}} of
162object {{obj}}.  The first term of the method is {{obj}}, and one or
163more {{arg}} are the remaining terms.  If no such slot exists, an
164error is signaled.
165
166<procedure>(object-apply/noslot-thunk obj noslot-thunk slot-symbol { arg }*)</procedure>
167
168Like {{object-apply}}, except that, if the slot does not exist,
169instead of signalling an error, the value is the result of applying
170{{noslot-thunk}}.
171
172<procedure>(object-raw-clone/no-slots-copy obj)</procedure>
173<procedure>(object-raw-clone/copy-immed-slots obj)</procedure>
174<procedure>(object-raw-clone/copy-all-slots obj)</procedure>
175
176These procedures implement different ways of cloning an object, and are
177generally bound as {{clone}} methods in root objects.
178{{/no-slots-copy}} does not copy any slots, {{/copy-immed-slots}}
179copes immediate slots, and {{/copy-all-slots}} copies all slots
180including inherited ones.
181
182<parameter>(current-root-object)</parameter>
183
184Parameter for the default root object.  The initial value is a root
185object that has {{object-raw-clone/no-slots-copy}} in its {{clone}}
186slot.
187
188Since Protobj's raison d'etre was to play with syntax, here it is.
189Note that slot names are never quoted.
190
191<macro>(^ obj)</macro>
192
193Parent of {{obj}}.
194
195<macro>(! obj slot val)</macro>
196<macro>(! obj)</macro>
197
198Sets object {{obj}}'s slot {{slot}}'s value to {{val}}.  In the second
199form of this syntax, multiple slots of {{obj}} may be set at once, and
200are set in the order given.
201
202<macro>(? obj { slot }+)</macro>
203
204Yields the values of the given {{slot}}s of {{obj}}.  If more than one
205{{slot}} is given, a multiple-value return is used.
206
207<macro>(@ obj slot { arg }*)</macro>
208<macro>(@ obj { (slot { arg }* ) }+)</macro>
209
210Applies {{obj}}'s {{slot}} method, with {{obj}} as the first term and
211{{arg}}s as the remaining terms.  In the second form of this syntax,
212multiple methods may be applied, and the value is the value of the
213last method application.
214
215<macro>(% [ obj { (slot val) }* ])</macro>
216
217Clones object {{obj}}, binding any given {{slot}}s to respective given
218{{val}}s.
219
220==== References
221
222; [LGPL] : Free Software Foundation, "GNU Lesser General Public License," Version
2232.1, February 1999, 59 Temple Place, Suite 330, Boston, MA 02111-1307
224USA. [[http://www.gnu.org/copyleft/lesser.html]]
225
226; [OScheme] : Anselm Baird-Smith, "OScheme." [[http://koala.ilog.fr/abaird/oscheme/om.html]]
227
228; [Self] : David Ungar and Randall B. Smith, "Self: The Power of Simplicity," ''Lisp and Symbolic Computation'', 4, 3, 1991.
229[[http://research.sun.com/self/papers/self-power.html]]
230
231; [SLIB-Object] : Wade Humeniuk, "Macroless Object System," SLIB {{object}}.
232[[http://swissnet.ai.mit.edu/~jaffer/slib_7.html#SEC180]]
233
234; [SRFI-9] : Richard Kelsey, "Defining Record Types," SRFI 9, 9 September 1999.
235[[http://srfi.schemers.org/srfi-9/srfi-9.html]]
236
237; [SRFI-23] : Stephan Houben, "Error reporting mechanism," SRFI 23, 26 April 2001.
238[[http://srfi.schemers.org/srfi-23/srfi-23.html]]
239
240; [SRFI-39] : Marc Feeley, "Parameter objects," SRFI 39, 30 June 2003.
241[[http://srfi.schemers.org/srfi-39/srfi-39.html]]
242
243; [Testeez] : Neil W. Van Dyke, "Testeez: Simple Test Mechanism for Scheme," Version 0.1.
244[[http://www.neilvandyke.org/testeez/]]
245
246=== Changelog
247
248* 0.2 Bugfix, {{$}} changed to {{?}}
249* 0.1 Initial release
250
251=== License
252
253  Copyright (c) 2005 Neil W. Van Dyke.  This program is Free
254  Software; you can redistribute it and/or modify it under the terms of the
255  GNU Lesser General Public License as published by the Free Software
256  Foundation; either version 2.1 of the License, or (at your option) any
257  later version.  This program is distributed in the hope that it will be
258  useful, but without any warranty; without even the implied warranty of
259  merchantability or fitness for a particular purpose.  See the GNU Lesser
260  General Public License [LGPL] for details.  For other license options and
261  commercial consulting, contact the author.
262
Note: See TracBrowser for help on using the repository browser.