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 3, the unsupported old release. You're almost certainly looking for [[/eggref/4/tinyclos|the CHICKEN 4 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-4.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags:eggs oop]] [[toc:]] == Introduction This extension is a port of Gregor Kiczales '''TinyCLOS''' with numerous modifications. ''Note: Before CHICKEN version 2.424, TinyCLOS was a core unit of CHICKEN. With CHICKEN version 2.424 and onwards, TinyCLOS is not part of the core, it is an an egg extension.'' ==== Defining forms ==== define-class [syntax] (define-class NAME (SUPERCLASS1 ...) (SLOTNAME1 ...) [METACLASS]) Sets the variable {{NAME}} to a new class (a new instance of the class {{<class>}}). {{SUPERCLASS1 ...}} is a list of superclasses of the newly created class. If no superclasses are given, then {{<object>}} is assumed. {{SLOTNAME1 ...}} are the names of the direct slots of the class. if {{METACLASS}} is provided, then the new class-instance is an instance of {{METACLASS}} instead of {{<class>}}. (define-class NAME (SUPER) (SLOT1 SLOT2) META) is equivalent to (define NAME (make META 'name 'NAME 'direct-supers (list SUPER) 'direct-slots (list 'SLOT1 'SLOT2)) ) Note that slots-names are not required to be symbols, so the following is perfectly valid: (define hidden-slot (list 'hidden)) (define <myclass> (make <class> 'direct-supers (list <object>) 'direct-slots (list hidden-slot) ) ) (define x1 (make <myclass>) (slot-set! x1 hidden-slot 99) ==== define-generic [syntax] (define-generic NAME [CLASS]) Sets the variable {{NAME}} to contain a fresh generic function object without associated methods. If the optional argument {{CLASS}} is given, then the generic function will be an instance of that class. ==== define-method [syntax] (define-method (NAME (VARIABLE1 CLASS1) ... PARAMETERS ...) BODY ...) Adds a new method with the code {{BODY ...}} to the generic function that was assigned to the variable {{NAME}}. {{CLASS1 ...}} is a list if classes that specialize this particular method. The method can have additional parameters {{PARAMETERS}}, which do not specialize the method any further. Extended lambda-lists are allowed ({{#!optional, #!key}} or {{#!rest}} argument lists), but can not be specialized. Inside the body of the method the identifier {{call-next-method}} names a procedure of zero arguments that can be invoked to call the next applicable method with the same arguments. If no generic function is defined under this name, then a fresh generic function object is created and assigned to {{NAME}}. Note that only {{define-generic}} expands into a valid definition, so for internal lexically scoped definitions use {{define-generic}}. Currently methods defined with {{define-method}} should not be hidden (via {{(declare (hide ...))}}, nor should such files be compiled in {{block}} mode, unless the methods are exported. === Base language ==== add-method [procedure] (add-method GENERIC METHOD) Adds the method object {{METHOD}} to the list of applicable methods for the generic function {{GENERIC}}. ==== instance? [procedure] (instance? X) Returns {{#t}} if {{X}} is an instance of a non-primitive class. ==== make [procedure] (make CLASS INITARG ...) Creates a new instance of {{CLASS}} and passes {{INITARG ...}} to the {{initialize}} method of this class. ==== make-class [procedure] (make-class SUPERCLASSES SLOTNAMES) Creates a new class object, where {{SUPERCLASSES}} should be the list of direct superclass objects and {{SLOTNAMES}} should be a list of symbols naming the slots of this class. ==== make-generic [procedure] (make-generic [NAME]) Creates a new generic function object. If {{NAME}} is specified, then it should be a string. ==== make-method [procedure] (make-method SPECIALIZERS PROC) Creates a new method object specialized to the list of classes in {{SPECIALIZERS}}. (define-method (foo (x <bar>)) 123) <=> (add-method foo (make-method (list <bar>) (lambda (call-next-method x) 123))) ==== slot-ref [procedure] (slot-ref INSTANCE SLOTNAME) Returns the value of the slot {{SLOTNAME}} of the object {{INSTANCE}}. ==== slot-set! [procedure] (slot-set! INSTANCE SLOTNAME VALUE) [setter] (set! (slot-ref INSTANCE SLOTNAME) VALUE) Sets the value of the slot {{SLOTNAME}} of the object {{INSTANCE}} to {{VALUE}}. ==== slot@ [syntax] (slot@ OBJECT SLOTNAME ... [= VALUE]) Object slots are de-referenced by name left-to-right, with an optional last slot assignment. <enscript highlight=scheme> (slot@ foo x y) ;=> (slot-ref (slot-ref foo 'x) 'y) (slot@ foo x y = "bar") ;=> (slot-set! (slot-ref foo 'x) 'y "bar") </enscript> === Introspection ==== class-cpl [procedure] (class-cpl CLASS) Returns the class-precedence-list of {{CLASS}} as a list of classes. ==== class-direct-slots [procedure] (class-direct-slots CLASS) Returns the list of direct slots of {{CLASS}} as a list of lists, where each sublist contains the name of the slot. ==== class-direct-supers [procedure] (class-direct-supers CLASS) Returns the list of direct superclasses of {{CLASS}}. ==== class-of [procedure] (class-of X) Returns the class that the object {{X}} is an instance of. See Extensions below for an API to extend the set of "built-in" classes. ==== class-name [procedure] (class-name CLASS) Returns name of {{CLASS}}. ==== class-slots [procedure] (class-slots CLASS) Returns the list of all slots of {{CLASS}} and its superclasses as a list of lists, where each sublist contains the name of the slot. ==== generic-methods [procedure] (generic-methods GENERIC) Returns the list of all methods associated with the generic function {{GENERIC}}. ==== method-specializers [procedure] (method-specializers METHOD) Returns the list of classes that specialize {{METHOD}}. ==== method-procedure [procedure] (method-procedure METHOD) Returns the procedure that contains the body of {{METHOD}}. ==== subclass? [procedure] (subclass? CLASS1 CLASS2) Returns {{#t}} is {{CLASS1}} is a subclass of {{CLASS2}}, or {{#f}} otherwise. Note that the following holds: <enscript highlight=scheme> (subclass? X X) ==> #t </enscript> ==== instance-of? [procedure] (instance-of? X CLASS) Returns {{#t}} if {{X}} is an instance of {{CLASS}} (or one of its subclasses). === Intercessory protocol These definitions allow interfacing to the Meta Object Protocol of TinyCLOS. For serious use, it is recommended to consult the source code ({{tinyclos.scm}}). ==== allocate-instance [generic] (allocate-instance CLASS) Allocates storage for an instance of {{CLASS}} and returns the instance. ==== compute-apply-generic [generic] (compute-apply-generic GENERIC) Returns a procedure that will be called to apply the generic function methods to the arguments. ==== compute-apply-methods [generic] (compute-apply-methods GENERIC) Returns a procedure of two arguments, a list of applicable methods and a list of arguments and applies the methods. ==== compute-methods [generic] (compute-methods GENERIC) Returns a procedure of one argument. The procedure is called with the list of actual arguments passed to the generic function and should return a list of applicable methods, sorted by precedence. ==== compute-cpl [generic] (compute-cpl CLASS) Computes and returns the class-precedence-list of {{CLASS}}. ==== compute-getter-and-setter [generic] (compute-getter-and-setter CLASS SLOT ALLOCATOR) Returns two values, the procedures that get and set the contents of the slot {{SLOT}}. {{ALLOCATOR}} is a procedure of one argument that gets an initializer function and returns the getter and setter procedures for the allocated slot. ==== compute-method-more-specific? [generic] (compute-method-more-specific? GENERIC) Returns a procedure of three arguments (two methods and a list of arguments) that returns {{#t}} if the first method is more specific than the second one with respect to the list of arguments. Otherwise the returned predicate returns {{#f}}. ==== compute-slots [generic] (compute-slots CLASS) Computes and returns the list of slots of {{CLASS}}. ==== initialize [generic] (initialize INSTANCE INITARGS) Initializes the object {{INSTANCE}}. {{INITARGS}} is the list of initialization arguments that were passed to the {{make}} procedure. === Additional protocol ==== describe-object [generic] (describe-object INSTANCE [PORT]) Writes a description of {{INSTANCE}} to {{PORT}}. Execution of the interpreter command {{,d}} will invoke this generic function. If {{PORT}} is not given it defaults to the value of {{(current-output-port)}}. ==== print-object [generic] (print-object INSTANCE [PORT]) Writes a textual representation of {{INSTANCE}} to {{PORT}}. Any output of an instance with {{display, write}} and {{print}} will invoke this generic function. If {{PORT}} is not given it defaults to the value of {{(current-output-port)}}. === Utility procedures ==== initialize-slots [procedure] (initialize-slots INSTANCE INITARGS) This procedure takes a sequence of alternating slot-names and initialization values in {{INITARGS}} and initializes the corresponding slots in {{INSTANCE}}. <enscript highlight=scheme> (define-class <pos> () (x y)) (define-method (initialize (pos <pos>) initargs) (call-next-method) (initialize-slots pos initargs)) (define p1 (make <pos> 'x 1 'y 2)) (define p2 (make <pos> 'x 3 'y 5)) </enscript> ==== make/copy [procedure] (make/copy INSTANCE [INITARGS]) Returns a copy of the object {{INSTANCE}}. {{INITARGS}} is the list of initialization arguments that will override the {{INSTANCE}} copy slot values. === Builtin classes The class hierarchy of builtin classes looks like this: <enscript highlight=scheme> <top> <object> <class> <procedure-class> <entity-class> <generic> <primitive-class> <procedure> <c++-object> <primitive> <void> <boolean> <symbol> <char> <vector> <pair> <number> <integer> <exact> <inexact> <string> <port> <input-port> <output-port> <pointer> <tagged-pointer> <swig-pointer> <locative> <blob> <byte-vector> ; DEPRECATED <structure> <u8vector> <s8vector> <u16vector> <s16vector> <u32vector> <s32vector> <f32vector> <f64vector> <char-set> <condition> <continuation> <environment> <hash-table> <lock> <mmap> <mutex> <promise> <queue> <read-table> <regexp> <tcp-listener> <thread> <time> <end-of-file> </enscript> ==== <primitive> The parent class of the classes of all primitive Scheme objects. ==== boolean ==== symbol ==== char ==== vector ==== null ==== pair ==== number ==== integer ==== exact ==== inexact ==== string ==== port ==== environment ==== end-of-file ==== input-port ==== output-port ==== procedure The classes of primitive Scheme objects. ==== byte-vector ; DEPRECATED ==== blob ==== structure ==== hash-table ==== queue The classes of extended data types provided by the various library units. ==== class The parent class of all class objects. ==== entity-class The parent class of objects that can be invoked as a procedure and have slots. ==== generic The parent class of generic function objects. ==== method The parent class of method objects. ==== object The parent class of all objects. ==== procedure-class The parent class of objects that can be invoked as a procedure. ==== condition Class of condition objects. ==== continuation Class of continuation objects captured by {{continuation-capture}}. ==== array ==== char-set ==== time ==== u8vector ==== s8vector ==== u16vector ==== s16vector ==== u32vector ==== s32vector ==== f32vector ==== f64vector The classes of data objects provided by the various supplied SRFIs. ==== lock ==== mmap Classes of objects used in the {{posix}} library unit. ==== pointer ==== tagged-pointer ==== swig-pointer A machine pointer (untagged, tagged or pointing to SWIG-wrapped data). ==== locative A locative. ==== promise The class of objects returned by {{delay}}. ==== tcp-listener The class of an object returned by {{tcp-listen}}. ==== regexp The class of an object returned by {{regexp}}. ==== c++-object The class of generated wrappers for C++ classes parsed by the "easy" Foreign Function interface [[easyffi]]. === Extending {{class-of}} The {{class-of}} procedure can be extended to recognize additional classes beyond the builtin set. ==== define-primitive-class [syntax] (define-primitive-class NAME PREDICATE [SUPER-CLASS ...]) Defines a new primitive class, {{<NAME>}}, with type predicate procedure {{PREDICATE}}, and the super-classes {{SUPER-CLASS ...}}. When a {{SUPER-CLASS}} is not specified the class {{<primitive>}} is assumed. The {{PREDICATE}} procedure takes the object to test as the lone parameter, and returns {{#f}} for failure. Any existing class with the same {{PREDICATE}} will be replaced! [procedure] (##tinyclos#delete-primitive-class CLASS) Remove the {{CLASS}} from the extended set of primitive classes. ==== define-structure-class [syntax] (define-structure-class NAME TAG) Defines a new structure class, {{<NAME>}}, with {{class-of}} structure type symbol {{TAG}}. Any existing class with the same {{TAG}} will be replaced! [procedure] (##tinyclos#delete-structure-class CLASS) Remove the {{CLASS}} from the extended set of structure classes. ==== define-tagged-pointer-class [syntax] (define-tagged-pointer-class NAME TAG) Defines a new tagged-pointer class, {{<NAME>}}, with {{class-of}} tagged-pointer type symbol {{TAG}}. Any existing class with the same {{TAG}} will be replaced! [procedure] (##tinyclos#delete-tagged-pointer-class CLASS) Remove the {{CLASS}} from the extended set of tagged-pointer classes. ==== define-extended-procedure-class [syntax] (define-extended-procedure-class NAME PREDICATE) Defines a new extended-procedure class, {{<NAME>}}, with type predicate procedure {{PREDICATE}}. The {{PREDICATE}} procedure takes the extended-data to test as the lone parameter, and returns {{#f}} for failure. Any existing class with the same {{PREDICATE}} will be replaced! [procedure] (##tinyclos#delete-extended-procedure-class CLASS) Remove the {{CLASS}} from the extended set of extended-procedure classes. == Authors Orignal version by Gregor Kiczales, CHICKEN port and performance enhancements by [[/users/felix winkelmann|felix winkelmann]], some of which have been inspired by Eli Barzilays ''Swindle'' {{slot@}} from the '@' macro by [[Dan Muresan]]. == License Copyright (c) 2000-2007, Felix L. Winkelmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == Version History ; 1.5 : fixed use of obsolete reader hack ; 1.404 : added {{make/copy}} [Kon Lovett] ; 1.403 : added unbound error to {{class-of}} [Kon Lovett] ; 1.402 : fixed bug in {{class-of}} that caused crash when passed void [felix winkelmann] ; 1.401 : Uses ':optional' (for older Chicken) [Kon Lovett] ; 1.4 : Added class-of extension api, and slot@. Much internal re-ordering [Kon Lovett] ; 1.3 : removed unnecessary feature-registration [thanks to Matthew Welland] ; 1.2 : removed use of {{:optional}} in {{tinyclos.scm}} [thanks to Todd Ingalls] ; 1.1 : added missing {{syntax}} indicator in setup script ; 1.0 : moved from base distribution into separate extension
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 7 from 16?