In article <··············@deb.lib.aero.>, Ari Krupnik <···@lib.aero>
wrote:
> I'm writing a recursive function, and I find myself asking, how many
> invocations of this function are currently on the stack? What's the
> value of a local variable 5 invocations down the stack? I could give
> the function an extra argument that contained a list of states the
> function had gone through, but this seems wrong:
>
> (defun f (args &optional history)
> ...
> (setf local-state (make-hash-table))
You should use LET to create a local variable, not assign a global
variable.
> ...
> (f (cdr args) (cons local-state history))
>
>
> Is there a better way to do this in Lisp? Is this something
> continuations do? If there's a resource I should read, I would
> appreciate a pointer.
This doesn't seem like a common programming pattern, so I don't think
there's any built-in mechanism or well-known idiom. There's no standard
way to look things up in a particular stack frame -- you have to provide
your own way to access it.
Your hash-table approach requires you to explicitly copy the value of
each variable into the hash table. Instead, you could use a local
function to access the variables you care about:
(flet ((get-local-state (var)
(ecase var
(var1 var1)
(var2 var2)
...)))
(f (cdr args) (cons #'get-local-state history)))
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
In article <··············@deb.lib.aero.>, Ari Krupnik <···@lib.aero>
wrote:
> Barry Margolin <······@alum.mit.edu> writes:
> > Your hash-table approach requires you to explicitly copy the value of
> > each variable into the hash table. Instead, you could use a local
> > function to access the variables you care about:
> >
> > (flet ((get-local-state (var)
> > (ecase var
> > (var1 var1)
> > (var2 var2)
> > ...)))
> > (f (cdr args) (cons #'get-local-state history)))
>
> This looks very powerful, much more useful then the hash table I
> imagined. But I'm confused--shouldn't the keys be quoted? Otherwise,
> it seems to me the values of the local variables will become the keys,
> not their names:
> ('var1 var1)
> ('var2 var2)
CASE doesn't evaluate that part of the subform, so quoting is not
required. In fact, CASE allows you to put a list of objects there, e.g.
(ecase thing
((thing1 thing2) ...)
((thing3 thing4 thing5) ...)))
Since 'var1 is just shorthand for (quote var1), what you wrote would be
equivalent to:
(ecase var
((quote var1) var1)
((quote var2) var2))
which would cause the value of VAR1 to be returned if VAR's value were
the symbol QUOTE.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***