[net.sources] XLISP, modified, one more try

john@x.UUCP (John Woods) (09/17/84)

[ How many Zen Masters does it take not to eat the first line of a message? ]

First, thanks to all who have written with comments and bug fixes (including
sftri!mjm, apollo!nazgul, and a cast of (thousands *) ).  I am preparing a new
release of XLISP, which I will FIRST try to bring up on a PDP-11/44 at MIT,
JUST TO MAKE SURE that this stuff works (those who were disappointed by my
first try, I did my penance at MIT-CCC...).

To those who noticed:  the "self = NULL;" bug was introduced due to a problem
involved in getting an error while an object is active:  the object's instance
variables remain active.  The *correct* fix is incorporated in the new code
(no one figured it out, and my head is now bloody from banging my head against
a wall):  the *binding* of self must be cleared (self->n_symvalue = NULL;).
It should now reset correctly.  By the way, I disagree with the implementation,
but I am leaving it alone:  if self is bound to non-nil, the instance variables
of self are checked FIRST, before the environment.  This means that if I have
an "x" instance variable, and define a function with a local variable "x",
and use that function as a method for the given object, I lose.  The proper
fix (from my point of view) is either to just lambda bind them, or (better)
when you add an instance variable to an object, a method should be
automagically defined which gets that variable (in the style of the MIT flavor
system's GET-variable methods, which are brewed up by defflavor and its co-
conspirators), as well as one to set the variable.  But, I have left it alone
(Dave, are you listening?).

To give you all something to do while I get this *really* *ready* to go, I
offer the following example of the use of the object system (someone asked
me for an example, and it took me quite some time to figure it out on my
own.  The documentation ought to tell more about instance variables).
This example declares a ship class, gives it some appropriate variables,
and then defines a function which creates objects of type ship, initializing
the instance variables.  It is not a terribly useful example, but it should
help people who are still confused.

			BEGIN EXAMPLE OF CLASSES
(setq ship (Class 'new))	; make a class known as ship

(ship 'ivars '(x y xv yv m name captain registry)) ; some instance variables

(ship 'answer 'getx		'() '( x ))	; just evaluate x
(ship 'answer 'getxv		'() '( xv ))	; note that the method is a
(ship 'answer 'gety		'() '( y ))	; list of forms, the value
(ship 'answer 'getyv		'() '( yv ))	; of the last one being the
(ship 'answer 'getm		'() '( m ))	; value of the method
(ship 'answer 'getname		'() '( name ))
(ship 'answer 'getcaptain	'() '( captain ))
(ship 'answer 'getregistry	'() '( registry ))

;			   formal
;			   param
;			   of
;			   method
(ship 'answer 'setx  	   '(to) '( (setq x to) ) )
(ship 'answer 'setxv 	   '(to) '( (setq xv to) ) )
(ship 'answer 'sety  	   '(to) '( (setq y to) ) )
(ship 'answer 'setyv	   '(to) '( (setq yv to) ) )
(ship 'answer 'setm	   '(to) '( (setq m to) ) )
(ship 'answer 'setname     '(to) '( (setq name to) ) )
(ship 'answer 'setcaptain  '(to) '( (setq captain to) ) )
(ship 'answer 'setregistry '(to) '( (setq registry to) ) )

(ship 'answer 'sail '(time) 
	; the METHOD for sailing
	'( (princ "sailing for " time " hours\n")
	   ; note that this form is expressed in terms of objects:  "self"
	   ; is bound to the object being talked to during the execution
	   ; of its message.  It can ask itself to do things.
	   (self 'setx (+  (self 'getx)
			   (* (self 'getxv) time)))
	   ; This form performs a parallel action to the above, but more
	   ; efficiently, and in this instance, more clearly
	   (setq y (+ y (* yv time)))
	   ; Cute message for return value.  Tee Hee.
	   "Sailing, sailing, over the bountiful chow mein..."))

; <OBJECT: #12345667> is not terribly instructive.  How about a more
; informative print routine?

(ship 'answer 'print '() '((princ
				"SHIP NAME: " (self 'getname) "\n"
				"REGISTRY: " (self 'getregistry) "\n"
				"CAPTAIN IS: " (self 'getcaptain) "\n"
				"MASS IS: " (self 'getm) " TONNES\n"
				"CURRENT POSITION IS: " 
					(self 'getx)	" X BY "
					(self 'gety)	" Y\n"
				"SPEED IS: "
					(self 'getxv)	" XV BY "
					(self 'getyv)	" YV\n") ) )

; a function to make life easier

(defun newship (mass name registry captain / new)
	(setq new (ship 'new))
	(new 'setx 0)
	(new 'sety 0)
	(new 'setxv 0)
	(new 'setyv 0)
	(new 'setm mass)
	(new 'setname name)
	(new 'setcaptain captain)
	(new 'setregistry registry)
	(print new)
	new)

; and an example object.

(setq Bounty (newship 50 'Bounty 'England 'Bligh))
			END EXAMPLE OF CLASSES

If all goes well, the next release from me will be sometime tomorrow.
-- 
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1114
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA

I have absolutely nothing clever to say in this signature.