[net.emacs] Parameters and recursion

kentb@uo-vax1.UUCP (04/08/84)

Could someone please explain the following strangeness in passing parameters
to recursive mlisp functions?  Here is an example:

(defun
    (foo bar
      (setq bar (arg 1 "bar? "))
      (message (concat "foo of " bar)) 
      (sit-for 20)
      (if (> bar 0)
	(progn
	  (message (concat "(- bar 1) is " (- bar 1))) 
	  (sit-for 20)
	  (foo (- bar 1))))))

Calling foo with 4 as an argument produces the messages-
  foo of 4
  (- bar 1) is 3  
  foo of -1

Help!!!!
(tektronix | hp-pcd)!uoregon!uo-vax1!kentb

Kent L. Beck, baffled mlisp hack...

notes@iuvax.UUCP (04/11/84)

#R:uo-vax1:-1020000200:iuvax:2300005:000:820
iuvax!unix68    Apr 10 18:22:00 1984

I remember figuring this one out when I first started writing mlisp code.
The reason for the behaviour is that the passed arguments are not
evaluated until the called function actually asks for them to be
evaluated and they are then evaluated in the CALLED function's current
environment rather than the CALLING function's environment.

Since bar is a local variable, when (setq bar (arg 1 "bar? "))
is executed the second time, bar is 'lambda bound' to 0, and
(arg 1 "bar? ") is the value of (- bar 1) IN THE CURRENT ENVIRONMENT
RATHER THAN THE CALLING ENVIRONMENT and is thus equivalent to
(- 0 1) or -1.

I don't know whether this is considered a 'bug' or a 'feature', but
I think that this is one of the things that got changed (to work the
way you would expect) when the new, alternative, defun syntax was
created.