From: Jonathan LF King
Subject: Can a program access stack-depth?
Date: 
Message-ID: <xndhf2if4gu.fsf@maxwell.math.ufl.edu>
Dear Cognoscenti [The questions are below.  I first describe what
I'm doing now in case someone wants to suggest a better or more
standard way to accomplish this.]

  I am (v.e.r.y slowly) writing a group of routines to compute
various elem. number theory objects.  In the loop (of each routine
which has a loop) there is debugging code where it prints out what
I think it is doing.

  I would like to arrange that this printing only occurs when the
routine is called at top level.  (I currently have a poor man's
version of that.)

  More generally, does CL� have a function `stack-depth' so that
if form `(stack-depth)' is exceuted in routine C inside of B
inside of A called from the top level, then it returns `3'.

  Then I'd have a 
	(defvar *PRINT-THRESHOLD* 1)
and my debug/print routines would first test
	(if (<= (stack-depth) *PRINT-THRESHOLD*) (print <diagnostic info>))

The questions:

Q1: Is there a `stack-depth' fnc in CL?  Is there one that runs in
Emacs lisp�?

Q2: Is there a standard way to accomplish what I am looking for?

	Sincerely, -Jonathan
-- 
Prof. Jonathan LF King	  Mathematics dept, Univ. of Florida
<······@math.ufl.edu>,	  <http://www.math.ufl.edu/~squash/>

From: Rahul Jain
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <954o6c$c1e$1@joe.rice.edu>
In article <···············@maxwell.math.ufl.edu> on
<···············@maxwell.math.ufl.edu>, "Jonathan LF King"
<······@math.ufl.edu> wrote:

>   I would like to arrange that this printing only occurs when the
> routine is called at top level.  (I currently have a poor man's version
> of that.)
[...] 
> Q2: Is there a standard way to accomplish what I am looking for?

(defun foo (x)
  (format t "foo called with argument ~a" x)
  (real-foo x))

(defun real-foo (x)
  ...)

Is that what you're looking for?
If you're using generic-functions, you could use a :before method to
print the debugging information instead.

-- 
-> -/-                       - Rahul Jain -                       -\- <-
-> -\- http://linux.rice.edu/~rahul -=- ·················@usa.net -/- <-
-> -/- "I never could get the hang of Thursdays." - HHGTTG by DNA -\- <-
|--|--------|--------------|----|-------------|------|---------|-----|-|
   Version 11.423.999.220020101.23.50110101.042
   (c)1996-2000, All rights reserved. Disclaimer available upon request.
From: Joe Marshall
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <7l3dssgf.fsf@content-integrity.com>
Jonathan LF King <······@math.ufl.edu> writes:

> Dear Cognoscenti [The questions are below.  I first describe what
> I'm doing now in case someone wants to suggest a better or more
> standard way to accomplish this.]
> 
>   I am (v.e.r.y slowly) writing a group of routines to compute
> various elem. number theory objects.  In the loop (of each routine
> which has a loop) there is debugging code where it prints out what
> I think it is doing.
> 
>   I would like to arrange that this printing only occurs when the
> routine is called at top level.  (I currently have a poor man's
> version of that.)
> 
>   More generally, does CL� have a function `stack-depth' so that
> if form `(stack-depth)' is exceuted in routine C inside of B
> inside of A called from the top level, then it returns `3'.

Nope.

> 
>   Then I'd have a 
> 	(defvar *PRINT-THRESHOLD* 1)
> and my debug/print routines would first test
> 	(if (<= (stack-depth) *PRINT-THRESHOLD*) (print <diagnostic info>))
> 
> The questions:
> 
> Q1: Is there a `stack-depth' fnc in CL?  Is there one that runs in
> Emacs lisp�?

There isn't in CL.  You could probably hack one into some
implementations of CL using the debugger.


> Q2: Is there a standard way to accomplish what I am looking for?

I'd recommend learning more about the debugging tools for the Lisp you
are using.  I think you might find them a bit more flexible.

There are a few ways of doing what you asked for, though.  One way
that comes to mind is to wrap a let binding around the functions of
interest:

(defvar *current-depth* 0
   "Holds the `stack depth' of certain functions.")

(defun func1 (x y z)
  (let ((*current-depth* (1+ *current-depth*)))
     ...whatever func1 does...
     ))

You could then inspect *current-depth* at any time to see how `deep'
you are for the functions of interest.

The trickier part is trying to `automate' the above.  

There are a few ways of doing this.  You could make a macro:

(defmacro with-stack-depth-tracing ((depth format-string &rest format-args) &body body)
  `(LET ((*CURRENT-DEPTH* (1+ *CURRENT-DEPTH*)))
     (WHEN (<= *CURRENT-DEPTH* ,depth)
       (FORMAT *TRACE-OUTPUT* ,format-string ,@format-args))
     ,@body))

So you could write:

(defun func1 (x y z)
  (with-stack-depth-tracing (3 "~&In func1, x is ~d" x)
     ...whatever func1 does....))

If you want *every* function you write to work like this, you wouldn't
want to manually write the let expression (it is visual clutter, it
would be duplicated everywhere and thus hard to change or remove, you
might forget it sometime, and retyping it is a source of typo errors).

(defmacro debugging-defun (name arglist &rest body)
  `(DEFUN ,name ,arglist
     (LET ((*CURRENT-DEPTH* (1+ *CURRENT-DEPTH*)))
       ,@body)))

Or you could even shadow the common lisp DEFUN (not generally
recommended).

(defmacro defun (name arglist &rest body)
  `(CL:DEFUN ,name ,arglist
     (LET ((*CURRENT-DEPTH* (1+ *CURRENT-DEPTH*)))
       ,@body)))

The problem with the above methods is that they unconditionally
annotate your code.  You are tracking the stack depth whether you want
to or not.

Some common lisps provide an `advice' facility that allows you to
modify function definition at runtime.  Using this, you could define
a wrapper:

(if you were using allegro CL, this would work)

(excl:advise-1 'func1 :around 'track-stack-depth nil
  '((let ((*current-depth* (1+ *current-depth*)))
      :do-it)))

And then you could advise those functions that you want to track the
depth.  If you wanted *all* of them, you could map over the symbols in
your package and advise the ones bound to functions.  This has the advantage that
when you are done, you can simply remove the advice.

If your CL doesn't include an advice facility, you can fake the
above. 

(let ((original-function (symbol-function 'func1)))
  (setf (symbol-function 'func1)
        (stack-depth-wrapper original-function)))

(defun stack-depth-wrapper (original-function)
  #'(lambda (&rest args)
      (let ((*current-depth* (1+ *current-depth*)))
        (apply original-function args))))

But I would still recommend trying to use the debugger rather than
resort to these methods.

Hope this helps.

> 	Sincerely, -Jonathan
> -- 
> Prof. Jonathan LF King	  Mathematics dept, Univ. of Florida
> <······@math.ufl.edu>,	  <http://www.math.ufl.edu/~squash/>


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Jonathan LF King
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <xndlmramom3.fsf@maxwell.math.ufl.edu>
Thank you Messieurs Rahul Jain, Joe Marshall and Jeff Greif, for your
suggested solutions.  I too had thought of wrapper-macros around DEFUN
contents, with the equivalent of (incf level) upon entering the DEFUN
and (decf level) upon leaving.  Among my misgivings were

1: One has to handle THROW&CATCH correctly.

2: It seems a terrible waste to try to duplicate some stack
information, when CL already knows this information, and CL is, I
presume,k better-debugged than my code is ever going to be.

  I confess to being quite bewildered that the CL spec doesn't specify
read-only inspection functions for the non-implementation-dependent
aspects of (am I using the correct term here?) the invocation-stack.

  It seems like such a CL kind of thing to do --was this an oversight,
or was there a reason not to provide such inspection functions?  (Or
am I wrong about this being "a CL kind of thing to do"?)

	Sincerely, -Jonathan
-- 
Prof. Jonathan LF King	  Mathematics dept, Univ. of Florida
<······@math.ufl.edu>,	  <http://www.math.ufl.edu/~squash/>
From: Duane Rettig
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <4n1bqkw8q.fsf@beta.franz.com>
Others have answered you in other articles, saying basically that
it is simply not specified due to lack of a low-level model of
a stack that can be guaranteed to be portable.  That said:

Jonathan LF King <······@math.ufl.edu> writes:

> Thank you Messieurs Rahul Jain, Joe Marshall and Jeff Greif, for your
> suggested solutions.  I too had thought of wrapper-macros around DEFUN
> contents, with the equivalent of (incf level) upon entering the DEFUN
> and (decf level) upon leaving.  Among my misgivings were
> 
> 1: One has to handle THROW&CATCH correctly.
> 
> 2: It seems a terrible waste to try to duplicate some stack
> information, when CL already knows this information, and CL is, I
> presume,k better-debugged than my code is ever going to be.

I agree.  It seems better to be able to examine the stack
programmatically instead of having to modify local environments
in order to model stack behavior.  Others have pointed out that
there are a number of reasons why the stack information might not
be the same.  However, there is an api that we use for our own
stack handling (it actually wasn't originally specified by us,
but by Sun at a time when Lucid and Franz were competing to become
Sun's lisp).  Our version of the interface is documented at:

http://www.franz.com/support/documentation/6.0/doc/debugger-api.htm

It contains capability to write enough introspection to answer the
question "What are the callers of this function?" or "is this the
first, second, third, etc. invocation of this function on this stack?"
among others.

Of course, this might not help you directly, but you may be able to
contact your lisp vendor to inquire whether their own such interface
is available programmatically.

>   I confess to being quite bewildered that the CL spec doesn't specify
> read-only inspection functions for the non-implementation-dependent
> aspects of (am I using the correct term here?) the invocation-stack.
> 
>   It seems like such a CL kind of thing to do --was this an oversight,
> or was there a reason not to provide such inspection functions?  (Or
> am I wrong about this being "a CL kind of thing to do"?)

In order to become part of CL, an interface has to be standardized.
And in order to be standardized, it has to be agreed upon.  There are
a number of systems that are not standard but useful, specific to each
vendor and possibly to each platform, such as foreign-function
interfaces, defsystem, and graphics apis.  For each of these, you must
contact your vendor or a third party.  But the lack of the same in the
CL spec doesn't mean that it can't be done, or that it isn't done as a
normal course of events.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Tim Bradshaw
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <nkjn1bq8l3r.fsf@tfeb.org>
Jonathan LF King <······@math.ufl.edu> writes:

> 
>   I confess to being quite bewildered that the CL spec doesn't specify
> read-only inspection functions for the non-implementation-dependent
> aspects of (am I using the correct term here?) the invocation-stack.
> 
>   It seems like such a CL kind of thing to do --was this an oversight,
> or was there a reason not to provide such inspection functions?  (Or
> am I wrong about this being "a CL kind of thing to do"?)
> 

I think it's not a CL thing to do, because it's likely to be *so*
implementation-dependent.  The very notion of a call stack is kind of
implementation-dependent, what goes on it could just vary wildly --
for instance there may be all sorts of secret frames in there that you
don't expect: imagine a fairly obvious implementation of WITH-type macros as 

	(with-x (...) ...) -> (call-with-x #'(lambda (...) ...) ...)

now there is (may be?) an extra frame on the stack.  What about
tail-call optimisation?  Inlining?  As to knowing anything more than
the depth -- who is to say that the names are even there any more?
It's just a huge tangled implementation-specific mess.

For your specific worry about catch/throw &c the right thing to do is
to use specials, which have to deal with this: make a
function-defining macro which binds *stack-depth* (a special variable,
global value 0) to (1+ *stack-depth*) around the body of the function.

--tim
From: Lieven Marchand
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <m3k86uclwd.fsf@localhost.localdomain>
Jonathan LF King <······@math.ufl.edu> writes:

>   I confess to being quite bewildered that the CL spec doesn't specify
> read-only inspection functions for the non-implementation-dependent
> aspects of (am I using the correct term here?) the invocation-stack.
> 

I think you'll find there are no non-implementation-dependent aspects
of an invocation-stack. For instance, on an IBM mainframe under VM/CMS
(and possibly under other OS'es for it) there is a linked list of
activation records that is in no way organized as a stack. Also, under
some mode of compilation (e.g. something like CMUCL block-compile with
high levels of optimization) the compiler may be able to integrate so
much of the called functions into their callers that there isn't much
left of the standard calling convention.

-- 
Lieven Marchand <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.
From: Jeff Greif
Subject: Re: Can a program access stack-depth?
Date: 
Message-ID: <YZEd6.202$SM5.2097@dca1-nnrp2.news.digex.net>
Here's a workable (but not very elegant or hygienic) solution that does not
need any notion of stack depth.  Only the outermost call to any of the
functions using with-print-shadowing will print anything.  This will not get
only the calls at top level, but only the outermost.

(defvar *print-threshold* 0)

;;; assumes there is a local variable current-print-threshold!
(defmacro print-diagnostics (&body body)
  `(if (= current-print-threshold 0)
      ,@body))

;;; body will usually contain a call to print-diagnostics
(defmacro with-print-shadowing (&body body)
  `(let* ((current-print-threshold *print-threshold*)
          (*print-threshold* (1+ *print-threshold*)))
     ,@body))

(defun a-number-theory-function (some args)
  (with-print-shadowing
     (let ((result (eulers-totient some args)))
        (print-diagnostics
          (format ...))
 result)))

(defun another-number-theory-function (some args)
  (with-print-shadowing
     (let ((result (number-of-primes-between some args)))
        (print-diagnostics
          (format ...))
 result)))

Jeff

"Jonathan LF King" <······@math.ufl.edu> wrote in message
····················@maxwell.math.ufl.edu...
>
> Dear Cognoscenti [The questions are below.  I first describe what
> I'm doing now in case someone wants to suggest a better or more
> standard way to accomplish this.]
>
>   I am (v.e.r.y slowly) writing a group of routines to compute
> various elem. number theory objects.  In the loop (of each routine
> which has a loop) there is debugging code where it prints out what
> I think it is doing.
>
>   I would like to arrange that this printing only occurs when the
> routine is called at top level.  (I currently have a poor man's
> version of that.)