L.Parkes@comp.vuw.ac.nz (Lloyd Parkes) (08/27/90)
I am currently working on an OO database engine for a MUD. I have decided to use xlisp for this (I need OO more than database stuff). I have a couple of questions though. 1) Why does xset() call setvalue(), while xsetq() calls xlsetvalue() to do it's work? As things stand at the moment, set will only set the global value of a symbol. 2) Why doesn't xlobget/setvalue search the ivars of the object being sent the message, when looking for local bindings of symbols? Why should it? I wanted to hack things for my OO system. The way I have done it is to check the ivars of the recieving object after the other ivars & cvars have been checked. This means I may scope out a global symbol from a method if a child class has an ivar with the same name, but at least I won't scope out an ivar or cvar that used to be in scope. Lloyd p.s. I know #2 isn't all that wonderfull, but it does let you hack things, particularly with #1. p.p.s I am an xlisp neophyte, but I am very good at C. -- ------------------------------------------------------------------------ Lloyd Parkes | lloyd@comp.vuw.ac.nz | ------------------------------------------------------------------------
mayer@hplabsz.HPL.HP.COM (Niels Mayer) (08/28/90)
In article <1990Aug27.001721.9563@comp.vuw.ac.nz> L.Parkes@comp.vuw.ac.nz (Lloyd Parkes) writes: > 2) Why doesn't xlobget/setvalue search the ivars of the object > being sent the message, when looking for local bindings of > symbols? It does... Through the miracle of gnuemacs tags (M-.) , I traced out the following sequence of calls in xlisp 2.1: (eval...)-->xleval()-->xlgetvalue()-->xlxgetvalue()-->xlobgetvalue(): [from xlsym.c] |/* xlxgetvalue - get the value of a symbol */ |LVAL xlxgetvalue(sym) | LVAL sym; |{ | register LVAL fp,ep; | LVAL val; | | /* check the environment list */ | for (fp = xlenv; fp; fp = cdr(fp)) | | /* check for an instance variable */ + if ((ep = car(fp)) && objectp(car(ep))) { + if (xlobgetvalue(ep,sym,&val)) + return (val); | } | | /* check an environment stack frame */ | else { | for (; ep; ep = cdr(ep)) | if (sym == car(car(ep))) | return (cdr(car(ep))); | } | | /* return the global value */ | return (getvalue(sym)); |} [from xlobj.c] |/* xlobgetvalue - get the value of an instance variable */ |int xlobgetvalue(pair,sym,pval) | LVAL pair,sym,*pval; |{ | LVAL cls,names; | int ivtotal,n; | | /* find the instance or class variable */ | for (cls = cdr(pair); objectp(cls); cls = getivar(cls,SUPERCLASS)) { | | /* check the instance variables */ | names = getivar(cls,IVARS); | ivtotal = getivcnt(cls,IVARTOTAL); | for (n = ivtotal - getivcnt(cls,IVARCNT); n < ivtotal; ++n) { | if (car(names) == sym) { | *pval = getivar(car(pair),n); | return (TRUE); | } | names = cdr(names); | } | | /* check the class variables */ | names = getivar(cls,CVARS); | for (n = 0; consp(names); ++n) { | if (car(names) == sym) { | *pval = getelement(getivar(cls,CVALS),n); | return (TRUE); | } | names = cdr(names); | } | } | | /* variable not found */ | return (FALSE); |} Note the lines above marked with '+'. > Why should it? Because otherwise, what's the point of having instance variables, or OOP, for that matter. As to your other questions, hopefully somebody else will answer, as I am very busy. ------------------------------------------------------------------------------- Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com Human-Computer Interaction Department Hewlett-Packard Laboratories Palo Alto, CA. *
L.Parkes@comp.vuw.ac.nz (Lloyd Parkes) (08/30/90)
In article <5854@hplabsz.HPL.HP.COM> mayer@hplabsz.HPL.HP.COM (Niels Mayer) writes: In article <1990Aug27.001721.9563@comp.vuw.ac.nz> L.Parkes@comp.vuw.ac.nz (Lloyd Parkes) writes: > 2) Why doesn't xlobget/setvalue search the ivars of the object > being sent the message, when looking for local bindings of > symbols? It does... [ lots of imported code deleted ] The code in 2.1 only searches the instance variables of the class for which the method is defined, not the object that is being sent the message. This only crops up when you are playing around with super classes and inheritance of methods. What I was doing was trying to write a generic `set an instance variable' method for an entire class heirarchy. After I had `fixed' xlisp, wasn't very difficult, just yucky :-) As to your other questions, hopefully somebody else will answer, as I am very busy. Aren't we all :-( Lloyd -- ------------------------------------------------------------------------ Lloyd Parkes | But like, what is the point man? I mean lloyd@comp.vuw.ac.nz | what is the point? ------------------------------------------------------------------------
mayer@hplabsz.HPL.HP.COM (Niels Mayer) (08/31/90)
In article <LLOYD.90Aug30111545@embassy.comp.vuw.ac.nz> L.Parkes@comp.vuw.ac.nz (Lloyd Parkes) writes: >The code in 2.1 only searches the instance variables of the class for >which the method is defined, not the object that is being sent the >message. This only crops up when you are playing around with super >classes and inheritance of methods. What I was doing was trying to >write a generic `set an instance variable' method for an entire class >heirarchy. After I had `fixed' xlisp, wasn't very difficult, just >yucky :-) I guess I misunderstood what you meant in your prev posting. In Xlisp, Instance variables are part of an object instance; methods can access instance variables of their class, and their superclasses; you send messages to objects, and methods defined on the class or superclasses "answer" the message... If you are expecting methods on superclasses to be able to access instance variables defined on subclasses, then you are not using the Xlisp object system "correctly"... maybe you need to be using a more complex object system (e.g. CLOS) for the kind of things you are doing. The following code works in the version of XLISP I'm using in Winterp-1.01 (which uses a modified XLISP 2.1): | (setq class-0 | (send Class :new | '(ivar-0) ;new instance vars | )) | | (setq class-1 | (send Class :new | '(ivar-1) ;new instance vars | '() ;no class vars | class-0)) ;superclass | | (setq class-2 | (send Class :new | '(ivar-2) ;new instance vars | '() ;no class vars | class-1)) ;superclass | | (setq class-3 | (send Class :new | '(ivar-3) ;new instance vars | '() ;no class vars | class-2)) ;superclass | | (send class-3 :answer :printout '() | '( | (format T " ivar-0=~A\n ivar-1=~A\n ivar-2=~A\n ivar-3=~A\n" | ivar-0 ivar-1 ivar-2 ivar-3) | )) | | (send class-3 :answer :isnew '(v0 v1 v2 v3) | '( | (setq ivar-0 v0) | (setq ivar-1 v1) | (setq ivar-2 v2) | (setq ivar-3 v3) | )) | | (setq inst0 | (send class-3 :new 'just 'say 'no "to bugs") | ) | (setq inst1 | (send class-3 :new 'means 'fight 'a "war on bugs") | ) | (setq inst2 | (send class-3 :new 'if 'panama 'was "a police action") | ) | (setq inst3 | (send class-3 :new 'why 'do 'they "call it a war on drugs?") | ) | | (send inst0 :printout) | (send inst1 :printout) | (send inst2 :printout) | (send inst3 :printout) The four :printout message-sends at the end give the following results... : Xlisp-Eval-Result: ivar-0=JUST : ivar-1=SAY : ivar-2=NO : ivar-3=to bugs : Xlisp-Eval-Result: ivar-0=MEANS : ivar-1=FIGHT : ivar-2=A : ivar-3=war on bugs : Xlisp-Eval-Result: ivar-0=IF : ivar-1=PANAMA : ivar-2=WAS : ivar-3=a police action : Xlisp-Eval-Result: ivar-0=WHY : ivar-1=DO : ivar-2=THEY : ivar-3=call it a war on drugs? ------------------------------------------------------------------------------- Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com Human-Computer Interaction Department Hewlett-Packard Laboratories Palo Alto, CA. *