From: Barry Margolin
Subject: Re: Stack access--Am I looking for continuations?
Date: 
Message-ID: <barmar-3262C2.20572909072007@comcast.dca.giganews.com>
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 ***
From: Barry Margolin
Subject: Re: Stack access--Am I looking for continuations?
Date: 
Message-ID: <barmar-6E0B76.00364811072007@comcast.dca.giganews.com>
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 ***