home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- XSCHEME 0.28 OBJECTS PRIMER
- February 23, 1992
-
- derived from the XLISP 2.0 OBJECTS PRIMER
- written by Tim I Mikkelsen on February 3, 1990
-
-
-
-
- Original copyright notice:
-
- Copyright (c) 1990 by Tim I. Mikkelsen. All Rights Reserved.
- No part of this document may be copied, reproduced or translated
- for commercial use without prior written consent of the author.
- Permission is granted for non-commercial use as long as this
- notice is left intact.
-
- Mine:
- Do what you like with it as long as it doesn't conflict with
- Tim's copyright notice.
- ________________________________________________________________
-
-
- One of the features in the design of XSCHEME is object-oriented
- programming. This primer is intended to serve as a very brief
- introduction to the object facilities of the XSCHEME 0.28
- dialect of SCHEME. Note that the object features of XSCHEME are
- not based on other existing object definitions in other SCHEME
- dialects. If you find problems in the primer, I'd appreciate
- hearing.
-
- Gunnar Zoetl
- Talstrasse 32
- D-6074 Roedermark
- Germany
-
- E-Mail: gunnar@fasel.hotb.sub.org
-
- However, note that I have not written this primer, but modified
- the original version by Tim Mikkelsen to suit XSCHEME instead of
- XLISP. Some bits of the message descriptions are taken from the
- XLISP 1.5 Manual by D. M. Betz and also modified. If you find it
- good, it's probably Tim's, if it's weird, it might be mine ;-)
-
- Tim's address is: David's address is:
- Tim Mikkelsen stated on the front
- 4316 Picadilly Drive page of his manual.
- Fort Collins, Colorado 80526
-
-
- PROGRAMMING STYLES
- ______________________________________________________________________________
-
-
- There are many programming paradigms (models). Some of the paradigms
- are procedural, functional, rule-based, declarative and object-oriented.
- A language can have aspects of one or many of these programming models.
-
-
- Procedure-Oriented
-
- The programming paradigm most people are familiar with is the procedural
- style. The primitives in procedural programming are: subroutines and
- data structures. Through these primitives, programmers have some
- limited abilities to share programs and program fragments. C and Pascal
- are examples of procedural languages. Some procedural languages (such
- as Modula and ADA) have extensions that provide for better sharing of
- code.
-
-
- Object-Oriented Programming
-
- Object-oriented programming is based on the primitives of objects,
- classes and messages. Objects are defined in terms of classes. Actions
- occur by sending a message to an object. An object's definition can be
- inherited from more general classes. Objective-C and C++ both are
- object-oriented dialects of the C language. Many dialects of LISP have
- some object oriented extension (Flavors, Common LOOPS, CLOS and others).
- There currently is standards work proceeding to add object-oriented
- programming to Common LISP.
-
-
- Object Oriented Programming
-
- So, the object-oriented programming model is based around the concepts
- of objects, classes and messages. An object is essentially a black box
- that contains internal state information. You send an object a message
- which causes the object to perform some operation. Objects are defined
- and described through classes.
-
- One aspect of an object is that you do not have to know what is inside -
- or how it works - to be able to use it. From a programming point of
- view, this is very handy. You can develop a series of objects for
- someone to use. If you need to change what goes on inside, the users of
- the objects should be unaware.
-
- Another aspect of objects is that of inheritance. You can build up new
- classes from existing classes by inheriting the existing class's
- functionality and then extending the new definition. For example, you
- can define a tool class (with various attributes) and then go about
- creating object instances tool-1, tool-2, and so on. You can also
- create new sub-classes of the tool class like power-tool. This is also
- very handy because you don't have to re-implement something if you can
- build it up from existing code.
-
-
-
-
- XSCHEME OBJECT-ORIENTED PROGRAMMING
- ______________________________________________________________________________
-
-
-
- XSCHEME OBJECT TERMINOLOGY
-
- There are, as previously mentioned, many different languages with
- object-oriented extensions and facilities. The terminology, operations
- and styles of these are very different. Some of the main definitions
- for XSCHEME's object-oriented extensions are:
-
- Object data type The OBJECT DATA TYPE is a built-in data
- type of XSCHEME. Members of the object
- data type are object instances and
- classes.
-
- Object instances An OBJECT INSTANCE is a composite
- structure that contains internal state
- information, methods (the code which
- respond to messages), a pointer to the
- object instance's defining class and a
- pointer to the object's super-class.
- XSCHEME contains no built-in object
- instances.
-
- Class objects A CLASS OBJECT is, essentially, the
- template for defining the derived object
- instances. A class object, although
- used differently from a simple object
- instance, is structurally a member of
- the object data type. It is also
- contains the linking mechanism that
- allows you to build class hierarchies
- (sub-classes and super-classes). XSCHEME
- contains two built-in class objects:
- OBJECT and CLASS.
-
- Message selector The MESSAGE SELECTOR is the symbol that
- is used to select a particular action
- (Method) from the object.
-
- Message The MESSAGE is the combination of the
- message selector and the data (if any)
- to be sent to the object.
-
- Method The METHOD is the actual code that gets
- executed when the object receives the
- Message.
-
-
-
- SENDING MESSAGES
-
- Message sending in XSCHEME is done by specifying the destination object,
- the message selector and the arguments to be passed to the selected
- method in the following way: (<object> <selector> [<argument>...])
- <object>, <selector> and the <argument>s are evaluated.
-
- The way that a user creates a new object is to send a 'NEW message to a
- previously defined class. The result of this send will return an
- object, so this is normally preceded by a SET! or DEFINE. I will use
- SET! throughout this document, for the exact difference see the
- "Revised^3 Report on the Algorithmic Language Scheme" or the Xscheme
- manual. The values shown in the examples that follow may not match what
- you see if you try this on your version of XSCHEME - this is not an
- error. The screens that are used in the various examples are similar
- to what you should see on your computer screen. The ">" is the normal
- XSCHEME prompt (the characters that follow the prompt is what you should
- type in to try these examples).
-
-
- ________________________________________________________________
- |
- | > (set! my-object (object 'new))
- | #<Object #48340>
- |________________________________________________________________
-
-
- The object created here is of limited value. Most often, you create a
- class object and then you create instances of that class. So in the
- following example, a class called MY-CLASS is created that inherits its
- definition from the a built-in CLASS definition. Then two instances are
- created of the new class.
-
- ________________________________________________________________
- |
- | > (set! my-class (class 'new '()))
- | #<Object #47f20>
- | > (set! my-instance (my-class 'new))
- | #<Object #47b90>
- | > (set! another-instance (my-class 'new))
- | #<Object #4786c>
- |________________________________________________________________
-
-
-
- CLASSES
-
- Previously, a 'NEW message was used to create an object. The message
- used to see what is in an object is the 'SHOW message.
-
- ________________________________________________________________
- |
- | > (my-class 'show)
- | Object is #<Object #47f20>, Class is #<Object #2e4c4>
- | messages = ()
- | ivars = (%%class)
- | cvars = #<Environment #47efc>
- | superclass = #<Object #2e5b4>
- | ivarcnt = 0
- | ivartotal = 0
- | #<Object #47f20>
- |________________________________________________________________
-
-
- From the display of the MY-CLASS object you can see there are a variety
- of components. The components of a class are:
-
- Class Pointer "Class is #<Object #2e4c4>"
- This pointer shows to what class the
- object (instance or class) belongs. For
- a class, this always points to the
- built-in object CLASS. This is also
- true of the CLASS object, its class
- pointer points to itself.
-
- Superclass Pointer "superclass = #<Object #2e5b4>"
- This pointer shows what the next class
- up the class hierarchy is. If the user
- does not specify what class is the
- superclass, it will point to the
- built-in class OBJECT.
-
- Messages "messages = ()"
- This component shows what messages are
- allowed for the class, and the
- description of the method that will be
- used. If the method is system-defined,
- it will show up in the form of '#<Subr
- %CLASS-NEW>'. Remember that the class
- hierarchy (through the Superclass
- Pointer) is searched if the requested
- message is not found in the class.
-
- Instance Variables "ivars = (%%class)"
- This component lists what instance
- variables will be created when an object
- instance is created. If no instances of
- the class exist, there are no Instance
- Variables. If there are 5 instances of
- a class, there are 5 complete and
- different groups of the Instance
- Variables.
-
- Class Variables "cvars = #<Environment #47efc>"
- This component shows the environment
- in which the class variables exist for
- the given class. Class Variables are
- used to hold state information about a
- class. There will be one of each of the
- Class Variables, independent of the
- number of instances of the class created
-
- A BETTER EXAMPLE
-
- The example previously shown does work, but the class and instances
- created don't really do anything of interest. The following example
- sets up a tool class and creates some tool instances.
-
- ________________________________________________________________
- |
- | > (set! my-tools (class 'new '(power moveable operation)))
- | #<Object #48208>
- |
- | > (my-tools 'answer 'isnew '(pow mov op)
- | '((set! power pow)
- | (set! moveable mov)
- | (set! operation op)
- | self))
- | #<Object #48208>
- |
- | > (set! drill (my-tools 'new 'AC t 'holes))
- | #<Object #46edc>
- |
- | > (set! hand-saw (my-tools 'new 'none t 'cuts))
- | #<Object #46594>
- |
- | > (set! table-saw (my-tools 'new 'AC nil 'cuts))
- | #<Object #460cc>
- |________________________________________________________________
-
-
- So, a class of objects called MY-TOOLS was created. Note that the class
- object MY-TOOLS was created by sending the 'NEW message to the built-in
- CLASS object. Within the MY-TOOL class, there are three instances
- called DRILL, HAND-SAW and TABLE-SAW. These were created by sending the
- 'NEW message to the MY-TOOLS class object. Notice that the parameters
- followed the message selector.
-
-
- INSTANCES
-
- The following is a display of the contents of some of the previously
- created instances:
-
- ________________________________________________________________
- |
- | > (drill 'show)
- | Object is #<Object #46edc>, Class is #<Object #48208>
- | power = ac
- | moveable = #t
- | operation = holes
- | #<Object #46edc>
- |
- | > (hand-saw 'show)
- | Object is #<Object #46594>, Class is #<Object #48208>
- | power = none
- | moveable = #t
- | operation = cuts
- | #<Object #46594>
- |________________________________________________________________
-
-
- From the display of these instances you can see there are some
- components and values. The components of an instance are:
-
- Class Pointer "Class is #<Object #12345>"
- This pointer shows to which class the
- current object instance belongs. It is
- through this link that the system finds
- the methods to execute for the received
- messages.
-
- Instance Variables "power = none ..."
- and Values The Instance Variables (IVAR) component
- lists what variables exist within the
- instance. The Instance Values component
- holds what the current values of the
- variables are. Instance Variables are
- used to hold state information for each
- instance. There will be a group of
- Instance Variables for each instance.
-
-
-
-
- METHODS
-
- There have been a few of the messages and methods in XSCHEME shown to this
- point ('NEW and 'SHOW). The following are the methods built into XSCHEME:
-
- 'answer <msg> <fargs> <code>
- where:
- <msg> the message symbol
- <fargs> the formal argument list
- this list is of the form:
- ([<farg>]...
- [#!optional [<oarg>]...]
- [#!rest <rarg>]
- [#!aux [<aux>]...])
- where
- <farg> a formal argument
- <oarg> an optional argument
- (default is nil)
- <rarg> bound to the rest of
- the arguments
- <aux> a auxiliary variable
- (set to nil)
- <code> a list of executable expressions
- The 'ANSWER method allows you to define or
- change methods within a class.
- returns: the object.
-
-
- 'isnew <ivars> [<cvars>[<super>]]
- where:
- <ivars> the list of instance variables
- <cvars> the list of class variables (default is nil)
-
-
- <super> the superclass (default is Object)
- The 'ISNEW method causes an instance to run its
- initialization code. When the 'ISNEW method is
- run on a class, it resets the class state. This
- allows you to re-define instance variables,
- class variables, etc.
- returns: the object.
-
- 'new <parameters>
- The 'NEW method allows you to create an instance
- when the 'NEW message is sent to a user-defined
- class. The 'NEW method allows you to create a
- new class (when the 'NEW message is sent to the
- built-in CLASS).
- When a new instance of a class is created by
- sending the message new" to an existing class,
- the message "'isnew" followed by whatever
- parameters were passed to the "'new" message is
- sent to the newly created object. When a new
- class is created by sending the "'new" message
- to the object "Class", an optional parameter may
- be specified indicating the superclass of the
- new class. If this parameter is omitted, the
- new class will be a subclass of Object". A
- class inherits all instance variables, class
- variables, and methods from its super-class.
- returns: the newly defined object
-
- 'show
- The 'SHOW method displays the instance or class.
- returns: the object.
-
- 'class
- The 'CLASS method returns the class of an object.
- returns: the object.
-
-
- When you redefine one of the methods selected by these these messages
- for your own classes, which will be most common for the 'isnew message,
- be careful to return the same as the original method does.
-
- SENDING MESSAGES TO A SUPERCLASS
-
- The SEND-SUPER function causes the specified message to be performed by
- the superclass method. SEND-SUPER is used in the same way a message is
- sent, i.e. (sendsuper <selector> [<argument>...]). This is a mechanism
- to allow chaining of methods in a class hierarchy. This chaining
- behavior can be achieved by creating a method for a class with the
- 'ANSWER message. Within the body of the method, you include a
- SEND-SUPER form. This function is allowed only inside the execution of
- a method of an object.
-
-
- OBJECT AND CLASS
-
- The definition of the built-in class OBJECT is:
-
- ________________________________________________________________
- |
- | > (object 'show)
- | Object is #<Object #2e5b4>, Class is #<Object #2e4c4>
- | messages = ((show . #<Subr %OBJECT-SHOW>)
- | (class . #<Subr %OBJECT-CLASS>)
- | (isnew . #<Subr %OBJECT-ISNEW>))
- | ivars = (%%class)
- | cvars = ()
- | superclass = ()
- | ivarcnt = 0
- | ivartotal = 0
- | #<Object #2e5b4>
- |________________________________________________________________
-
-
- Note that OBJECT is a class - as opposed to an "instance-style" object.
- OBJECT has no superclass, it is the top or root of the class hierarchy.
- OBJECT's class is CLASS.
-
- ________________________________________________________________
- |
- | > (class 'show)
- | Object is #<Object #2e4c4>, Class is #<Object #2e4c4>
- | messages = ((answer . #<Subr %CLASS-ANSWER>)
- | (isnew . #<Subr %CLASS-ISNEW>)
- | (new . #<Subr %CLASS-NEW>))
- | ivars = (%%class messages ivars cvars superclass
- | ivarcnt ivartotal)
- | cvars = ()
- | superclass = #<Object #2e5b4>
- | ivarcnt = 6
- | ivartotal = 6
- | #<Object #2e4c4>
- |________________________________________________________________
-
-
- CLASS has a superclass of OBJECT. It's class is itself - CLASS.
-
-
-
-
- A MORE REALISTIC EXAMPLE
- ______________________________________________________________________________
-
-
- The following is an example, using the idea of tools again. It contains
- a hierarchy of tool classes. The top of the class hierarchy is TOOLS.
- HAND-TOOLS and SHOP-TOOLS are sub-classes of TOOLS. The example creates
- instances of these sub-classes. It is possible to extend this example
- in various ways. One obvious extension would be to create a third tier
- of classes under HAND-TOOLS that could contain classes like drills,
- screwdrivers, pliers and so on.
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; File name: tools.s
- ;
- ; original XLISP-version:
- ;
- ; Author: Tim Mikkelsen
- ; Description: Object-oriented example program
- ; Language: XLISP 2.0
- ;
- ; Date Created: 10-Jan-1988
- ; Date Updated: 2-Apr-1989
- ;
- ; (c) Copyright 1988, by Tim Mikkelsen, all rights reserved.
- ; Permission is granted for unrestricted non-commercial use.
- ;
- ; port to XScheme:
- ;
- ; Language: Xscheme 0.28
- ;
- ; Date Created: 23-Feb-1992
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Define the superclasses and classes
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; make TOOLS superclass
- ; with a different 'ISNEW method
- ; added methods are 'BORROW and 'RETURN
- ; class variables are NUMBER contains # of tool instances
- ; ACTIVE-LIST contains list of current objects
-
-
- ; instance variables are POWER list - (AC BATTERY HAND)
- ; MOVEABLE CAN-CARRY or CAN-ROLL or FIXED
- ; OPERATIONS list
- ; MATERIAL list - (WOOD METAL PLASTIC ...)
- ; PIECES list
- ; LOCATION HOME or person's name
- ;
-
- (set! tools (class 'new '(power
- moveable
- operations
- material
- pieces
- location)
- '(number active-list)))
- (tools 'answer 'isnew '()
- '((if (null? number) (set! number 1)
- (set! number (1+ number)))
- (set! active-list (cons self active-list))
- (set! location 'home)
- self))
- (tools 'answer 'borrow '(by-who)
- '((if (eq? location 'home) (set! location by-who)
- (display "you can't"))))
- (tools 'answer 'return '()
- '((if (eq? location 'home) (display "got it already")
- (set! location 'home))))
-
- ;
- ; make HAND-TOOLS class
- ; with a different 'ISNEW method
- ; new instance variable WEIGHT <number> of pounds
- ; the rest is inherited from TOOLS
- ;
-
- (set! hand-tools (class 'new '(weight) '() tools))
- (hand-tools 'answer 'isnew '(pow op mat parts w-in)
- '((set! power pow)
- (set! moveable 'can-carry)
- (set! operations op)
- (set! material mat)
- (set! pieces parts)
- (set! weight w-in)
- (send-super 'isnew)))
-
- ;
- ; make SHOP-TOOLS class
- ; with a different 'ISNEW method
- ; no new instance variables
- ; the rest is inherited from TOOLS
- ;
-
- (set! shop-tools (class 'new '() '() tools))
- (shop-tools 'answer 'isnew '(pow mov op mat parts)
- '((set! power pow)
- (set! moveable mov)
- (set! operations op)
- (set! material mat)
- (set! pieces parts)
- (send-super 'isnew)
- self))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Create instances of various tool classes
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (set! hand-drill (hand-tools 'new ; make an instance - HAND-DRILL
- '(ac)
- '(drill polish grind screw)
- '(wood metal plastic)
- '(drill drill-bits screw-bits buffer)
- '2.5))
-
- (set! table-saw (shop-tools 'new ; make an instance - TABLE-SAW
- '(ac)
- 'fixed
- '(rip cross-cut)
- '(wood plastic)
- '(saw blades fence)))
-
-
- (set! radial-arm (shop-tools 'new ; make an instance = RADIAL-ARM
- '(ac)
- 'can-roll
- '(rip cross-cut)
- '(wood plastic)
- '(saw blades dust-bag)))
-
-
-
-
- The following session shows how to use the tool definitions from this
- better example. The example loads "tools.s" into xscheme.
- ________________________________________________________________
- |
- | > (load "tools.s")
- | #t
- |
- | > (hand-drill 'borrow 'fred)
- | fred
- |
- | > (table-saw 'return)
- | got it already#t
- |
- | > (hand-drill 'borrow 'joe)
- | you can't#t
- |
- | > (hand-drill 'return)
- | home
- |________________________________________________________________
-
-
- So, Fred was able to borrow the HAND-DRILL. When an attempt was made to
- return the TABLE-SAW, it was already at home. A second attempt to
- borrow the HAND-DRILL indicated that "you can't" because it was already
- lent out. Lastly, the HAND-DRILL was returned successfully. (Note that
- the "got it already" and "you can't" strings show up twice in the
- display because the methods both print and return the string.)
-
- The following session shows the structure of the TOOLS object:
-
- ________________________________________________________________
- |
- | > (tools 'show)
- | Object is #<Object #477f4>, Class is #<Object #2e4c4>
- | messages = ((return . #<Method RETURN>)
- | (borrow . #<Method BORROW>)
- | (isnew . #<Method ISNEW>))
- | ivars = (%%class power moveable operations material
- | pieces location)
- | cvars = #<Environment #47758>
- | superclass = #<Object #2e5b4>
- | ivarcnt = 6
- | ivartotal = 6
- | #<Object #477f4>
- |________________________________________________________________
-
-
- The two TOOLS sub-classes HAND-TOOLS and SHOP-TOOLS structure looks like:
-
- ________________________________________________________________
- |
- | > (hand-tools 'show)
- | Object is #<Object #45e68>, Class is #<Object #2e4c4>
- | messages = ((isnew . #<Method ISNEW>))
- | ivars = (%%class power moveable operations material
- | pieces location weight)
- | cvars = #<Environment #45e44>
- | superclass = #<Object #477f4>
- | ivarcnt = 1
- | ivartotal = 7
- | #<Object #45e68>
- |
- | > (shop-tools 'show)
- | Object is #<Object #452bc>, Class is #<Object #2e4c4>
- | messages = ((isnew . #<Method ISNEW>))
- | ivars = (%%class power moveable operations material
- | pieces location)
- | cvars = #<Environment #45298>
- | superclass = #<Object #477f4>
- | ivarcnt = 0
- | ivartotal = 6
- | #<Object #452bc>
- |________________________________________________________________
-
-
- The class HAND-TOOLS has an instance HAND-DRILL which looks like:
-
- ________________________________________________________________
- |
- | > (hand-drill 'show)
- | Object is #<Object #44464>, Class is #<Object #45e68>
- | power = (ac)
- | moveable = can-carry
- | operations = (drill polish grind screw)
- | material = (wood metal plastic)
- | pieces = (drill drill-bits screw-bits buffer)
- | location = home
- | weight = 2.5
- | #<Object #44464>
- |________________________________________________________________
-
-