From: Michael Hönisch
Subject: get-function-name
Date: 
Message-ID: <4174fea5$1@news.adm.arcor.net>
Hello,

I want to write a generic errorhandler-function. This function should 
return the functionname, where the error has happened in a dynamic way.

Is it possible to fetch the functionname from inside a function?

Regards
Michael

From: Frank Buss
Subject: Re: get-function-name
Date: 
Message-ID: <cl338r$64e$1@newsreader2.netcologne.de>
Michael H�nisch <················@ascad.de> wrote:

> I want to write a generic errorhandler-function. This function should 
> return the functionname, where the error has happened in a dynamic way.
> 
> Is it possible to fetch the functionname from inside a function?

you can redefine defun, but I'm not a Lisp expert, there might be 
problems with this:

(defparameter *function-backtrace* nil)
(shadow 'defun)
(defmacro defun (name arglist &rest body)
  `(cl:defun ,name ,arglist
     (push (quote ,name) *function-backtrace*)
     (unwind-protect
         ,@body
       (pop *function-backtrace*))))

Then for your functions you can get the backtrace:

CL-USER > (defun test () *function-backtrace*)
TEST

CL-USER > (defun test2 () (test))
TEST2

CL-USER > (test2)
(TEST TEST2)

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Tayssir John Gabbour
Subject: Re: get-function-name
Date: 
Message-ID: <1098197597.294946.220420@c13g2000cwb.googlegroups.com>
Frank Buss wrote:
> Michael Hönisch <················@ascad.de> wrote:
> > I want to write a generic errorhandler-function. This function
should
> > return the functionname, where the error has happened in a dynamic
way.
> >
> > Is it possible to fetch the functionname from inside a function?
>
> you can redefine defun, but I'm not a Lisp expert, there might be
> problems with this:

Reminds me of this thread, where lambda list destructuring was
mentioned.
http://groups.google.com/groups?hl=en&lr=&c2coff=1&safe=off&threadm=sfwd6by55if.fsf%40shell01.TheWorld.com&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26safe%3Doff%26c2coff%3D1%26q%3Ddefun%2Bdestructuring%26btnG%3DSearch%26meta%3Dgroup%253Dcomp.lang.lisp.*

&whole would be obviously useful for such uses like the original poster
wants. Maybe we need a metafunction protocol or something.

MfG,
Tayssir
From: Lars Brinkhoff
Subject: Re: get-function-name
Date: 
Message-ID: <85breydeqb.fsf@junk.nocrew.org>
Frank Buss <··@frank-buss.de> writes:
>      (push (quote ,name) *function-backtrace*)
>      (unwind-protect
>          ,@body
>        (pop *function-backtrace*))))

I suggest

        (let ((*function-backtrace* (cons ',name *function-backtrace*)))
          ,@body)

as an alternative for this particular fragment.

-- 
Lars Brinkhoff,         Services for Unix, Linux, GCC, HTTP
Brinkhoff Consulting    http://www.brinkhoff.se/
From: Pascal Bourguignon
Subject: Re: get-function-name
Date: 
Message-ID: <87acui3oaq.fsf@thalassa.informatimago.com>
Michael H�nisch <················@ascad.de> writes:

> Hello,
> 
> I want to write a generic errorhandler-function. This function should
> return the functionname, where the error has happened in a dynamic way.
> 
> Is it possible to fetch the functionname from inside a function?

Not portably. Moreover, a lot of functions don't have a name, or have
several names.

However, most implementations provides a way to recover the
backtrace. You could check the sources of slime to see how they do it.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Alan Crowe
Subject: Re: get-function-name
Date: 
Message-ID: <86pt3aqw3b.fsf@cawtech.freeserve.co.uk>
Michael Hoenisch wrote:
> I want to write a generic errorhandler-function. This
> function should return the functionname, where the error
> has happened in a dynamic way.

I've put a wrapper round defun to record the name

(defmacro defunam (name lambda-list &rest body)
  `(defun ,name ,lambda-list
     (handler-bind
      ((error (lambda(condition)
		(declare (ignore condition))
		(format *debug-io*
			"~&Trouble in (~S~{ ~S~})."
			',name ;here is the functions name
                        ;; I fail to handle keywords
			(list ,@lambda-list)))))
      ,@body)))

Then we can write functions. When an error is signalled, all
our functions list their names and arguments. 

Here is a simple example, which recurses down to zero before
signalling an error due to a failed assertion. The dynamic
path is printed.
				     
(defunam try (n)
  (assert (plusp n))
  (case (random 2)
    (0 (attempt (- n 1)))
    (1 (try (- n 1)))))

(defunam attempt (n)
  (assert (plusp n))
  (case (random 2)
    (0 (attempt (- n 1)))
    (1 (try (- n 1)))))

* (try 5)

Trouble in (ATTEMPT 0).
Trouble in (TRY 1).
Trouble in (ATTEMPT 2).
Trouble in (TRY 3).
Trouble in (TRY 4).
Trouble in (TRY 5).

Error in function COMMON-LISP::ASSERT-ERROR:
  The assertion (PLUSP N) failed.

etc

This has to use handler-bind, not handler-case.
If I had used handler-case, the first matching handler would
have handled the error and that would have been the end of
the matter.

With handler-bind you have to put a non-local exit in the
handler function (such as invoking a restart) in order to
"handle" the condition. If the handler function returns the CL
runtime tries the next one. All my handlers return so each
runs in turn, printing the function name and arguments,
before the CL runtime gets fed up and invokes the debugger.

I hope that gives you some ideas.

Alan Crowe
Edinburgh 
Scotland