Lisp Objects
Volume Number: | | 4
|
Issue Number: | | 4
|
Column Tag: | | Learning Lisp
|
Lisp Objects: Ford vs Chevy
By Didier Guillon, Grenoble, France
Didier Guillon is a former restaurant manager, currently in the fourth year of a Computer Science program at Grenoble University in France. He is a member of AAAI and works in artificial intelligence as a consultant at the Medical University of Grenobles department of BioStatistics. He is also president of Mac Alpes, a club of Macintosh developers in Grenoble and has been using the Mac for two years.
Welcome to this new column. When I first started Macintosh programming, MacTutor and the contributing editors were there and helped me since issue number one. Now I think its time to share with you the knowledge I gained with the oldest new language. So welcome to symbolic computation... you have a problem? No, dont be frightened, I have been so pleased when I discovered ABC s of C that I wanted to introduce you to the Lisp world in a gentle way. The technique I will use may sometimes be criticized by expert Lisp programmers...but do they remember their first steps?
Today I will present the object idea with a very dumb example and how to on the Macintosh. MacApp and MPW Pascal are there to let us remember that object programming becomes a reality day after day. But, since Smalltalk, no other language than Common Lisp did it with better efficiency.
My Kingdom for an Object
But what is an object ? To the outside world, an object is an entity. But for us programmers, an object is some private memory with a set of operations. An object can be a number, a square, a text editor. An object which is a square knows a lot of information about itself: how to calculate the area of the square, the center of the square... When we want the object square to carry out such a calculation, we send him a message (we say: to invoke). But we just tell him which operation we want, not how to operate. (If hes smart, he already knows that!)
When a set of objects represents the same kind of information, we implement a class with a data structure and the procedures that operate on this data structure. For example, a class implemented for a rectangle would know how a specific object, called an instance, would carry out the operation rectangular area. This instance has private variables called instance variables and the function that will operate on the instance of a particular class is call a method. We just defined in fact the fundamental concepts of object programming: data abstraction, information hiding (not to tell how to) and generic operation. But all this is just theory, so lets start with our dumb example. We will use the ExperCommonLisp (ECL) from ExperTelligence, who since the last review of this language in MacTutor, did a lot of improvement and removed many bugs.
First, lets create a class for cars (note: we wrote cars to avoid the car word which is a Lisp reserved word).
(defclass (cars object)
(IVS (color blue)
(price 0)))
Defclass contains a list with the name of the call and the name of the superclass. In ECL all the classes come from a special class called object. In fact object is a root class from which all classes are derived. The IVS stands for instance variable and as we saw previously, will manage to store the IVS in each instance. You note the quote before blue? In Lisp every elementary object, called an atom, is evaluated. This evaluation returns a function name or the value attached to this specific atom. So, to prevent evaluation, we quote the atom which becomes itself a value and is attached to the instance variable color. This quoting is not necessary for a numeric value. Then we define the method (using defmethod followed by the name of the class and the name of the method itself):
(defmethod (cars small) ()
(setq price 800)
(format T A small car is just fun for ~a dollars.~% price))
This method is doing two things: setting price to 800 with setq, a Lisp word which will not evaluate the following word, price, and sets its value to 800 (for Pascal programmers its an assignment). Then it prints a message (good old Fortran world !!!). You are now able to trace by yourself what the second method does:
(defmethod (cars race) ()
(setq color red)
(setq price 20000)
(format T A wonderful race car whose color is ~a.~% color))
Now we link up what we define to this first class: we compile and define an instance (we will represent the return value by ->):
(setq my1car (cars new))
-> #<CARS INSTANCE $5402341A>
my1car is the instance which holds a copy of the class cars. Lets invoke the instance in various ways :
(my1car race)
-> A wonderful race car whose color is RED.
(my1car small)
-> A small car is just fun for 800 dollars.
(my1car price)
-> 800
(my1car price 200)
-> 200
(my1car price)
-> 200
We can see the graphic image of the object we define, including the next subclass we will create:
Here is the subclass Ferrari:
(defclass (Ferrari cars)
(IVS a_speed))
(defmethod (cars buy_a_Ferrari) ()
(setq a_speed 200)
(self race)
(format T But when you drive at ~a miles... Whoo !!!!~% a_speed
) )
Same as the cars object, but note the self word which is used to invoke the method race from the method buy_a_Ferrari. As previously, we can say:
(setq I_buy_a_Ferrari (Ferrari new))
-> #<FERRARI INSTANCE $540233AA>
(I_buy_a_Ferrari buy_a_Ferrari)
-> A wonderful race car whose color is RED.
But when you drive at 200 miles... Whoo !!!!
(I_buy_a_Ferrari price)
-> 20000
(I_buy_a_Ferrari color)
-> RED
We can see easily that I_buy_a_Ferrari inherits from its superclass cars all the methods and instance variables. We will not cover here some other concepts like class variables, super....
So now that we have an idea on how objects live, well have a look at ECL. In ECL, the object idea has been expanded to the Macintosh Toolbox.
Before going on to the Macintosh toolbox, we have a look at another object expression, metamethod. A metamethod is a procedure which is invoked by sending an appropriate message to a class. We explain metamethod because on the Macintosh we create a NEW metamethod which sets up the required data structure. When invoking a specific metamethod, the instance of a particular class will have instance variables which will correlate (and with the same name) to the equivalent fields in the Pascal data structure. An example from QuickDraw:
(setq yourRect (Rect new 30 40 250 280))
We just created the instance call yourRect with a set of parameters. If we send it a message, we can access these instance accessors by the same name as in the Pascal structure : top, left, bottom, right.
(yourRect bottom)
-> 250
or change their value :
(yourRect left 60)
-> 60
We can also draw, calling Toolbox procedures with the instance yourRect :
(!PaintRect yourRect)
Note that trap names are prefixed by an exclamation mark. We are now ready to start programming our first minimum shell in ECL... but thats for next month.
For those interested in following me, and starting Lisp, I recommend the very nice and easy book of Touretzky A Gentle Introduction to Symbolic Computation. For the others, obviously, Lisp 2e by Winston is a must. I intend to present the next coming months various aspects of Lisp programming in Artificial Intelligence, but also use some special languages as OPS 5, SmallTalk, Humble, Prolog (or why not Nexpert, just to let us dream...). If you have any suggestions, please contact me :
Didier Guillon
8 Impasse Saint Jean
38240 Meylan
France.
The complete program :
(defclass (cars object)
(IVS (color blue)
(price 0)))
(defmethod (cars small) ()
(setq price 800)
(format T A small car is just fun for ~a dollars.~% price))
(defmethod (cars race) ()
(setq color red)
(setq price 20000)
(format T A wonderful race car whose color is ~a.~% color))
;**********Examples*****************
;(setq my1car (cars new))
;#<CARS INSTANCE $5402341A>
;(my1car race)
;A wonderful race car whose color is RED.
;(my1car small)
;A small car is just fun for 800 dollars.
;(my1car price)
;800
;(my1car price 200)
;200
;(my1car price)
;200
;**********Second class**************
(defclass (Ferrari cars)
(IVS a_speed))
(defmethod (Ferrari buy_a_Ferrari) ()
(setq a_speed 200)
(self race)
(format T But when you drive at ~a miles ... Whoo !!!!~%
a_speed))
;***********Example****************
;(setq I_buy_a_Ferrari (Ferrari new))
;#<FERRARI INSTANCE $540233AA>
;(I_buy_a_Ferrari buy_a_Ferrari)
;A wonderful race car whose color is RED.
;But when you drive at 200 miles... Whoo !!!!
;(I_buy_a_Ferrari price)
;20000
;(I_buy_a_Ferrari color)
;RED