From: David Andre
Subject: Obtaining the local variables in LISP
Date: 
Message-ID: <399DABBC.6E4AFDB6@cs.berkeley.edu>
Howdy.  I'd like to be able to find the names and values of all local
variables within a function in LISP.
Ideally, a function like (local-variables) would return a list of
variable-value pairs.  Does anyone know
of such a function?  The LISP debugger must have access to something
like this for when it displays local
variables.  Thank you very much for any help I receive on this.

Cheers,


--
-----------------------------------------------------------------------------
David Andre               UC Berkeley CS Division, Room 387 Soda Hall,
#1776
······@cs.berkeley.edu
http://http.cs.berkeley.edu/~dandre/

From: Rainer Joswig
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <joswig-675A7E.00460719082000@news.is-europe.net>
In article <·················@cs.berkeley.edu>, David Andre 
<······@cs.berkeley.edu> wrote:

> Howdy.  I'd like to be able to find the names and values of all local
> variables within a function in LISP.
> Ideally, a function like (local-variables) would return a list of
> variable-value pairs.  Does anyone know
> of such a function?  The LISP debugger must have access to something
> like this for when it displays local
> variables.  Thank you very much for any help I receive on this.

This is highly implementation dependant. There is no such thing
in portable Common Lisp. Implementations may or may not
record local variable names. MCL for example has a switch
for that:

  *SAVE-LOCAL-SYMBOLS*  
  [Variable]
  if true, compiled functions retain the names of parameters and local
  variables, for debugging purposes.

It also is not possible to access stack frames portably.

-> You need to tell what Lisp you are using.

-- 
Rainer Joswig, Hamburg, Germany
Email: ·············@corporate-world.lisp.de
From: David Andre
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <399DC50E.4114891C@cs.berkeley.edu>
Hi again.  Let me clarify.  I'm using Franz's Allegro Common Lisp.

I've just now found the tpl:do-command function and the file autozoom.cl
that is included with ACL, which gives the ability to print the backtrace
or the local variables to a stream, which is very close to what I want.
Say I have something that prints to a stream -- how can I shunt what would
go to the stream into a LISP
object that I could apply 'equal to?

Thanks again.

David Andre
From: Lieven Marchand
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <m366oxjp1s.fsf@localhost.localdomain>
David Andre <······@cs.berkeley.edu> writes:

> I've just now found the tpl:do-command function and the file autozoom.cl
> that is included with ACL, which gives the ability to print the backtrace
> or the local variables to a stream, which is very close to what I want.
> Say I have something that prints to a stream -- how can I shunt what would
> go to the stream into a LISP
> object that I could apply 'equal to?

Did you have something like this in mind?

USER(1): (defun square (x) (* x x))
SQUARE
USER(2): (trace square)
(SQUARE)
USER(3): (with-output-to-string (*trace-output*)
	   (square 2))
" 0: (SQUARE 2)
 0: returned 4
"

-- 
Lieven Marchand <···@bewoner.dma.be>
Lambda calculus - Call us a mad club
From: David Andre
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <39A1B4AC.80D0AB50@cs.berkeley.edu>
It seems that there is some confusion over what I'm attempting, so I will try to explain

it very clearly.

I'd like the following function to exist

(get-stack-locals [highest-to-look])

Where the function returns some structure (let's say, for now, just a nested list)

containing the function stack (just the names of each subroutine)

and an association list of variable names and their values.

The highest-to-look argument

just causes the list to be truncated at the first instance of the

subroutine named highest-to-look.

For example, let's

say we type in the following into lisp:

(setf foo nil)

(setf bar 8)

(defun bar3 (a b)

(setf foo (get-stack-locals))
  (* a b))

(defun bar2 (a b c)
  (let ((d 3))
    (bar3 (+ a b c) d)))

(defun bar1 (a)
  (let ((b 3) (c 2))
    (bar2 a b c)))

(bar1 bar)

What we'd like to see returned is something like:

((bar3 ((a 13) (b 3)))
 (bar2 ((a 8) (b 3) (c 2) (d 3)))
 (bar1 ((a 8) (b 3) (c 2)))
 (tpl ((bar 8)))

Although I can use tpl:do-command to get access to the debugger's commands

to output information to a stream, it would be much nicer to get the output in

clean variable format.

Furthermore, ideally, I'd get not the values of each variable, but pointers to

them so that I could then check the variables, thus allowing caching.

Any suggestions are welcome.  I am using Franz Common Lisp,

and vendor-dependent solutions are satisfactory.

Cheers,

David Andre

UC Berkeley CS Division, Room 387 Soda Hall, #1776

······@cs.berkeley.edu                  http://http.cs.berkeley.edu/~dandre/
From: Lieven Marchand
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <m3u2cd5ice.fsf@localhost.localdomain>
David Andre <······@cs.berkeley.edu> writes:

> Furthermore, ideally, I'd get not the values of each variable, but pointers to
> 
> them so that I could then check the variables, thus allowing caching.
> 
> Any suggestions are welcome.  I am using Franz Common Lisp,
> 
> and vendor-dependent solutions are satisfactory.
> 

I'm still not sure of what you want exactly or for what you'd want it,
but one way of doing this is by creating your own package shadowing
DEFUN and do a code walk over each defun body and expand
(get-stack-locals) in these bodies to whatever you want.

-- 
Lieven Marchand <···@bewoner.dma.be>
Lambda calculus - Call us a mad club
From: Kent M Pitman
Subject: Re: Obtaining the local variables in LISP
Date: 
Message-ID: <sfwem3iqctk.fsf@world.std.com>
David Andre <······@cs.berkeley.edu> writes:

> I'd like the following function to exist
> 
> (get-stack-locals [highest-to-look])
> 
> Where the function returns some structure (let's say, for now, 
> just a nested list)
> containing the function stack (just the names of each subroutine)

The reason there isn't such a function in the language itself is that
it's an abstraction violation which inhibits optimizations.  It's up
to implementations to provide it if they want, based on their own theory
of what information might be retained, based on how heavily they optimize.
But such a function would reveal whether an implementation was doing tail
call implementation (which the standard doesn't require and which correct 
user programs should not be able to tell, since they should not be relying
on its being done).  It would also be problematic for
  (defun f (y)
    (let ((x 3))
      (+ y x)))
where someone wanted to know the "local" value of x, even though the compiler
might have constant-folded it out.  Or for
  (defun f (y)
    (print y)
    (get-stack-locals))
where you might not find even the argument value was still available because
after the (print y) call, or even just after the setup for it, the y might
have been deactivated (maybe it was in a register, for example, that was needed
in the PRINT call).  It just isn't obvious what should and shouldn't be 
returned, and that's a mess.  People already quibble over functions like
(room) whose only valid use in a program is:
 (format t "~&(room) yielded: ~S~%")
since you don't even know if it will return a string or a list or whatever,
and you certainly don't know how to interpret the result.  In your case, you're
asking for the format of the return value to be specified, but not the
semantics, and that's only epsilon better.  It makes more sense in the context
of a specific implementation, but then it's the vendor and not the language
to which you should direct your request.