[net.emacs] Parameters and recursion Gosling Emacs MLisp

chris@umcp-cs.UUCP (04/11/84)

Ah yes, the old evaluation problem.  I think I know how to fix this, but
am not yet up to trying it.  The problem is that parameters are passed by
name:

(defun (foo bar
	...
	(foo bar)
	...

When the second "foo" is invoked, it gets one argument, namely the name
of the variable "bar".  When you subsequently access (arg 1), it sees
"bar" and proceeds to evaluate it.  Unfortunately, it gets the inner
"bar", rather than the outer one.  New variables are automatically set
to integer 0, so (arg 1) yeilds the integer 0, rather than the outer
value of bar.

There is a way to get around the problem:

(defun
    (factorial arg-1
	(setq arg-1 (arg 1))
	(progn k		; yes this is not the most efficient code
	    (setq k arg-1)	; in the world....
	    (if (> k 2)
		(* k (factorial (- k 1)))
		1)))
)
This is admittedly grotesque and obscure...

For anyone inclined to fix this, the method I am contemplating
involves adding a "ProgNDepth" variable, and changing the code that
accesses variables to search only to the current "EvalDepth"
(normally equal to the current ProgNDepth, but decreased by each
(arg) call, temporarily).  This is rather tricky; I think I may
have to change the entire data structure, or use a hack.  (By the
way, lest someone call me a liar:  the actual search is really in
the other order.  The most recent binding is the closest to the
VariableName structure and the "outer" bindings are farther away,
stashed in the "inner" pointer.  This implies that some fancy
footwork is required when EvalDepth != ProgNDepth.)
-- 
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@CSNet-Relay