From: Niels Mayer
Subject: Bug+Fix for xlisp2.0 method definition <-> Question: Should "defmethod" and "defmacro" use lexical scoping
Date: 
Message-ID: <3860@hplabsz.HPL.HP.COM>
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 #<Object: #136002>, Class is #<Object: #127f40>
	lisp>   A = 666
	lisp>   B = 777
	lisp>   C = 888
	lisp> #<Object: #136002>

				----------

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 -- ·····@hplabs.hp.com
		  Human-Computer Interaction Department
		       Hewlett-Packard Laboratories
			      Palo Alto, CA.
				   *