From sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer Fri Sep 1 08:29:10 EDT 1989 Article: 141 of comp.lang.lisp.x Path: cognos!sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer From: mayer@hplabsz.HPL.HP.COM (Niels Mayer) Newsgroups: comp.lang.lisp.x,comp.lang.lisp Subject: Bug+Fix for xlisp2.0 method definition <-> Question: Should "defmethod" and "defmacro" use lexical scoping Message-ID: <3860@hplabsz.HPL.HP.COM> Date: 26 Aug 89 13:37:22 GMT Reply-To: mayer@hplabs.hp.com (Niels Mayer) Organization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA. Lines: 83 Xref: cognos comp.lang.lisp.x:141 comp.lang.lisp:1787 Summary: Expires: Sender: Followup-To: In looking over the xlisp 2.0 objects code, I found a problem in xlobj.c:clanswer() in which I noticed that the :answer method on class Class does not save the lexical (xlenv) and functional (xlfenv) environments in the closure created by xlclose() during method definition. Thus, when the method gets evaluated, you get unbound symbol/function errors because the environment of the method call doesn't contain the bindings present in the definition's environment. [For you non xlispers out there, :answer defines a method on a class (essentially, a "defmethod").] Before I commit to my fix, I wanted to ask you all whether there is a good reason for NOT using the lexical and functional environment of a call to "defmethod" during a method evaluation. I would expect that you'd want to use lexical scoping for defining methods just like you would for defuns and lambdas. But I've been surprised before. Another case in which xlclose() isn't passed xlenv and xlfenv is in xlcont.c:xdefmacro(). Is there a reason why you wouldn't want to pass in the lexical environment of a call to defmacro? ---------- Here's some useless test code that illustrates the problem: lisp> (setq test_class (send Class :new '(a b c) '())) lisp> (let ( (x 666) (y 777) (z 888)) (send test_class :answer :isnew '() ;initialize method '( (setq a x) (setq b y) (setq c z) )) ) lisp> (setq i (send test_class :new)) Now, upon sending the :new message, I get the error mesage lisp> error: unbound variable - X After fixing the code in xlobj.c:clanswer(), I get the correct results: lisp> (send i :show) lisp> Object is #, Class is # lisp> A = 666 lisp> B = 777 lisp> C = 888 lisp> # ---------- Here's the patch: *** xlobj.c.~1~ Sat Aug 26 06:14:33 1989 --- xlobj.c Sat Aug 26 06:16:24 1989 *************** *** 277,283 /* setup the message node */ xlprot1(fargs); fargs = cons(s_self,fargs); /* add 'self' as the first argument */ ! rplacd(mptr,xlclose(msg,s_lambda,fargs,code,NIL,NIL)); xlpop(); /* return the object */ --- 277,283 ----- /* setup the message node */ xlprot1(fargs); fargs = cons(s_self,fargs); /* add 'self' as the first argument */ ! rplacd(mptr,xlclose(msg,s_lambda,fargs,code,xlenv,xlfenv)); /* changed by NPM -- pass in lexical and functional environment */ xlpop(); /* return the object */ ------------------------------------------------------------------------------- Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com Human-Computer Interaction Department Hewlett-Packard Laboratories Palo Alto, CA. *