[net.emacs] bug in arg passing

crl@CSvax:Pucc-H:pur-phy.UUCP (08/11/83)

I have found a bug in the argument passing code of (non-Unipress) EMACS.
Granted, I run a PDP-11 version, but I have tested it on Vaxen, and it
is still there.  The problem is evidenced by the following mlisp. Define
two functions:
(defun (foo a b
	   (setq a (arg 1))
	   (setq b (arg 2))
	   (message a b)
	   (novalue))
       (bar a b
	   (setq a "foo")
	   (setq b "bar")
	   (foo a b)
	   (novalue))
)
Call bar.  You would expect the message "foobar" to appear.  What happens
is that "00" appears.  Call (foo "foo" "bar")--you get "foobar".  Change
the variables 'a' and 'b' in bar to 'c' and 'd'--you get "foobar" now.

The problem is that in constructing the progn that is foo, the new
local variables 'a' and 'b' overlay the variables in bar.  The (arg)
call simply tries to evaluate the variable 'a', not knowing that the
new declaration has hidden the old.  Since the new one is automatically
initialized to 0, you get the message "00" instead.  I don't immediately
see a good way to handle this.  It means that all your "subroutines"
must use local variables that will never conflict.  For those of you
who have looked at the source, perhaps arguments should be evaluated
on the call and changed into StringNodes?

Charles LaBrec
pur-ee!Physics:crl
purdue!Physics:crl

thomas@utah-gr.UUCP (Spencer W. Thomas) (08/13/83)

We've discussed this one before.  It's not a bug, it's a feature!  But
seriously, it is annoying, but solving it would be a royal pain, I think.

Anybody who does it will have my undying gratitude (well, almost...).

=Spencer

chris@umcp-cs.UUCP (08/13/83)

That's not a bug, it's a feature!  :-)

The problem is that everything is a FEXPR (if I have my lisp terminology
correct):

(defun (foo1 z
	(setq z 10)
	(foo2 z)))
(defun (foo2 z
	(message "z = " z)))

exhibits the same problem.  ("z = 0")

The fix I have decided on is to write such functions as

(defun
    (foo1 arg1
	(setq arg1 (arg 1))
	(progn max-attempts i
	    (setq max-attempts arg1)
	    .
	    .
	    .

In other words, all arguments will put into be "arg1", "arg2", . . .
up until the actual code itself, which will be inside a progn which
declares the real variable names, and then moves the "arg"s to the
real variables.

This is essentially doing by hand what a real lisp system would do
for you (evaluating arguments before binding new variables).

				- Chris

PS You can even write recursive MLisp code this way!  (shudder)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris.umcp-cs@UDel-Relay

jag@jag@cmuitca.UUCP (08/15/83)

From:  James Gosling <cmuitca!jag@jag>

*sigh*  It is a feature, not a bug.  Clearly the product of
a diseased brain.  The only justification for it is that
(for example) the following implements a simple case
statement:

(defun (case
	  (arg (+ (arg 1) 1))))