Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for [[/eggref/5/protobj|the CHICKEN 5 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-5.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags: egg]] == protobj [[toc:]] === Description Prototype-Delegation Object Model in Scheme === Author Neil van Dyke === Documentation To use the definitions described in this document import its bindings by evaluating the {{(import protobj)}} form in the current scope. Protobj is a Scheme library that implements a simple prototype-delegation object model, somewhat similar to that of [Self], and also related to [SLIB-Object] and [OScheme]. Protobj was written mainly as a {{syntax-rules}} learning exercise, but also because people ask about prototype object models for Scheme from time to time. Like most object systems, it should be regarded as an amusement. The Protobj library defines both a verbose set of procedures, and terse special syntax. Protobj is based on objects with named slots that can contain arbitrary values. Object have immediate slots, and single parent objects from which additional slots are inherited. When setting in a child object a slot inherited from the parent, a new immediate slot is created in the child so that the parent is unaffected and the slot is no longer inherited. Methods are simply closures stored in slots. When a method is applied, the first term of the closure is the receiver object. Unlike Self, getting the contents of the slot is distinguished from invoking a method contained in the slot. This distinction was made due to the way first-class closures are often used in Scheme. An object is cloned by invoking the {{clone}} method. The default root object's {{clone}} method creates a new child object without any immediate slots, rather than copying any slots. This behavior can be overridden to always copy certain slots, to copy immediate slots, or to copy all inherited slots. An overriding {{clone}} method can be implemented to apply its parent's {{clone}} method to itself and then set certain slots in the new child appropriately. The following is a quick tour of Protobj using the terse special syntax. Bind {{a}} to the new object that is created by cloning the default root object ({{%}} is special syntax for invoking the {{clone}} method): (define a (%)) Verify that {{a}} is an object and that {{a}}'s parent is the default root object: (object? a) => #t (eq? (^ a) (current-root-object)) => #t Add to {{a}} a slot named {{x}} with value {{1}}: (! a x 1) Get {{a}}'s slot {{x}}'s value: (? a x) => 1 Bind {{b}} to a clone of {{a}}: (define b (% a)) Get {{b}}'s slot {{x}}'s value, which is inherited from {{a}}: (? b x) => 1 Set {{a}}'s slot {{x}}'s value to {{42}}, and observe that {{b}} inherits the new value: (! a x 42) (? a x) => 42 (? b x) => 42 Set {{b}}'s slot {{x}}'s value to {{69}}, and observe that {{a}} retains its own {{x}} value although {{b}}'s {{x}} value has been changed: (! b x 69) (? a x) => 42 (? b x) => 69 Add to {{a}} an {{xplus}} slot containing a closure that implements a method of the object: (! a xplus (lambda (self n) (+ (? self x) n))) Apply the method to the {{a}} and {{b}} objects ({{b}} inherits any new slots added to {{a}}): (@ a xplus 7) => 49 (@ b xplus 7) => 76 Observe the shorthand syntax for applying methods to an object multiple times, with the syntax having the value of the lastmost application: (@ a (xplus 1000) (xplus 7)) => 49 Bind to {{c}} an object that clones {{a}} and adds slot {{y}} with value {{101}}: (define c (% a (y 101))) Get the values of both the {{x}} and {{y}} slots of {{c}}: (? c x y) => 42 101 Finally, bind {{d}} to a clone of {{a}} that overrides {{a}}'s {{x}} slot: (define d (% a (x 1) (y 2) (z 3))) (? d x y z) => 1 2 3 The basic interface of Protobj is a set of procedures. <procedure>(object? x)</procedure> Predicate for whether or not {{x}} is a Protobj object. <procedure>(object-parent obj)</procedure> Yields the parent object of object {{obj}}. <procedure>(object-set! obj slot-symbol val)</procedure> Sets the slot identified by symbol {{slot-symbol}} in object {{obj}} to value {{val}}. <procedure>(object-get obj slot-symbol)</procedure> Yields the value of slot named by symbol {{slot-symbol}} in object {{obj}} (immediate or inherited). If no slot of that name exists, an error is signaled. <procedure>(object-get obj slot-symbol noslot-thunk)</procedure> Yields the value of slot named by symbol {{slot-symbol}} in object {{obj}} (immediate or inherited), if any such slot exists. If no slot of that name exists, then yields the value of applying closure {{noslot-thunk}}. <procedure>(object-apply obj slot-symbol { arg }*)</procedure> Applies the method (closure) in the slot named by {{slot-symbol}} of object {{obj}}. The first term of the method is {{obj}}, and one or more {{arg}} are the remaining terms. If no such slot exists, an error is signaled. <procedure>(object-apply/noslot-thunk obj noslot-thunk slot-symbol { arg }*)</procedure> Like {{object-apply}}, except that, if the slot does not exist, instead of signalling an error, the value is the result of applying {{noslot-thunk}}. <procedure>(object-raw-clone/no-slots-copy obj)</procedure> <procedure>(object-raw-clone/copy-immed-slots obj)</procedure> <procedure>(object-raw-clone/copy-all-slots obj)</procedure> These procedures implement different ways of cloning an object, and are generally bound as {{clone}} methods in root objects. {{/no-slots-copy}} does not copy any slots, {{/copy-immed-slots}} copes immediate slots, and {{/copy-all-slots}} copies all slots including inherited ones. <parameter>(current-root-object)</parameter> Parameter for the default root object. The initial value is a root object that has {{object-raw-clone/no-slots-copy}} in its {{clone}} slot. Since Protobj's raison d'etre was to play with syntax, here it is. Note that slot names are never quoted. <macro>(^ obj)</macro> Parent of {{obj}}. <macro>(! obj slot val)</macro> <macro>(! obj)</macro> Sets object {{obj}}'s slot {{slot}}'s value to {{val}}. In the second form of this syntax, multiple slots of {{obj}} may be set at once, and are set in the order given. <macro>(? obj { slot }+)</macro> Yields the values of the given {{slot}}s of {{obj}}. If more than one {{slot}} is given, a multiple-value return is used. <macro>(@ obj slot { arg }*)</macro> <macro>(@ obj { (slot { arg }* ) }+)</macro> Applies {{obj}}'s {{slot}} method, with {{obj}} as the first term and {{arg}}s as the remaining terms. In the second form of this syntax, multiple methods may be applied, and the value is the value of the last method application. <macro>(% [ obj { (slot val) }* ])</macro> Clones object {{obj}}, binding any given {{slot}}s to respective given {{val}}s. You can override the method {{print}} to customize printing of objects: <enscript highlight=scheme> (define x (%)) (! x print (lambda (self #!optional (port (current-output-port))) (fprintf port "#<my object>"))) </enscript> ==== References ; [LGPL] : Free Software Foundation, "GNU Lesser General Public License," Version 2.1, February 1999, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. [[http://www.gnu.org/copyleft/lesser.html]] ; [OScheme] : Anselm Baird-Smith, "OScheme." [[http://koala.ilog.fr/abaird/oscheme/om.html]] ; [Self] : David Ungar and Randall B. Smith, "Self: The Power of Simplicity," ''Lisp and Symbolic Computation'', 4, 3, 1991. [[http://bibliography.selflanguage.org/_static/self-power.pdf]] ; [SLIB-Object] : Wade Humeniuk, "Macroless Object System," SLIB {{object}}. [[http://swissnet.ai.mit.edu/~jaffer/slib_7.html#SEC180]] ; [SRFI-9] : Richard Kelsey, "Defining Record Types," SRFI 9, 9 September 1999. [[http://srfi.schemers.org/srfi-9/srfi-9.html]] ; [SRFI-23] : Stephan Houben, "Error reporting mechanism," SRFI 23, 26 April 2001. [[http://srfi.schemers.org/srfi-23/srfi-23.html]] ; [SRFI-39] : Marc Feeley, "Parameter objects," SRFI 39, 30 June 2003. [[http://srfi.schemers.org/srfi-39/srfi-39.html]] ; [Testeez] : Neil W. Van Dyke, "Testeez: Simple Test Mechanism for Scheme," Version 0.1. [[http://www.neilvandyke.org/testeez/]] === Changelog * 0.3 Added {{print}} method * 0.2 Bugfix, {{$}} changed to {{?}} * 0.1 Initial release === License Copyright (c) 2005 Neil W. Van Dyke. This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU Lesser General Public License [LGPL] for details. For other license options and commercial consulting, contact the author.
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 19 from 0?