24

In C there is the magic variable __func__ that holds the current function name. In Bash, there is an array FUNCNAME holding the names of all functions in the calling stack !!!

Is there a similar thing in Emacs Lisp? Or any simple way for a function to have access to its name?

I have not found any answer in the Emacs Lisp manual (chapter 12 on Functions or index of variables and functions and ..)

  • 2
    What do you actually need that for? – lunaryorn Oct 20 '14 at 14:27
  • 1
    It's not exactly a magic variable -- it's a pre-processor definition inserted by some compilers. – Sean Allred Jan 15 '15 at 21:46
6

For interactive functions, i.e., commands, you can use the variable this-command, or safer, real-this-command. The difference being that when you write your own functions, you can explicitly change the value of this-command. Mostly this is done to play tricks with last-command related to repeating commands. You shouldn't (can't?) do this with real-this-command. It will always be the name of the current command.

I'm not aware of an equivalent for non-interactive functions.

  • 3
    It's important to note that this-command and real-last-command are not at all like __func__. For instance if command A calls command B which prints this-command it will print command A, not B, also this does not work at all for functions. – Jordon Biondo Jan 15 '15 at 22:10
  • 1
    @JordonBiondo Agreed. I did note that it doesn't work for functions. phs didn't give us his context, so I guessed that this might be good enough for his application. Your answer is more robust, no question. – Tyler Jan 16 '15 at 19:50
22

Updated answer with expansion time lookup:

I said in my original answer that there may be a way to do this at expansion/compile time instead of run time to give better performance and I finally implemented that today while working on my answer for this question: How can I determine which function was called interactively in the stack?

Here is a function that yields all current backtrace frames

(defun call-stack ()
  "Return the current call stack frames."
  (let ((frames)
        (frame)
        (index 5))
    (while (setq frame (backtrace-frame index))
      (push frame frames)
      (incf index))
    (remove-if-not 'car frames)))

Using that in a macro we can look up the expansion stack to see what function definition is being expanded at the time and put that value right in the code.

Here is the function to do the expansion:

(defmacro compile-time-function-name ()
  "Get the name of calling function at expansion time."
  (symbol-name
   (cadadr
    (third
     (find-if (lambda (frame) (ignore-errors (equal (car (third frame)) 'defalias)))
              (reverse (call-stack)))))))

Here it is in action.

(defun my-test-function ()
  (message "This function is named '%s'" (compile-time-function-name)))

(symbol-function 'my-test-function)
;; you can see the function body contains the name, not a lookup
(lambda nil (message "This function is named '%s'" "my-test-function"))

(my-test-function)
;; results in:
"This function is named 'my-test-function'"

Original Answer:

You can use backtrace-frame to look up the stack until you see frame that represents a direct function call and get the name from that.

(defun get-current-func-name ()
  "Get the symbol of the function this function is called from."
  ;; 5 is the magic number that makes us look 
  ;; above this function
  (let* ((index 5)
         (frame (backtrace-frame index)))
    ;; from what I can tell, top level function call frames
    ;; start with t and the second value is the symbol of the function
    (while (not (equal t (first frame)))
      (setq frame (backtrace-frame (incf index))))
    (second frame)))

(defun my-function ()
  ;; here's the call inside my-function
  (when t (progn (or (and (get-current-func-name))))))

(defun my-other-function ()
  ;; we should expect the return value of this function
  ;; to be the return value of my-function which is the
  ;; symbol my-function
  (my-function))

(my-other-function) ;; => 'my-function

Here I am doing the function name lookup at runtime though it is probably possible to implement this at a macro that expands directly into the function symbol which would be more performant for repeat calls and compiled elisp.

I found this information while trying to write a sort of function call logger for elisp which can be found here in it's incomplete form, but it might be useful to you. https://github.com/jordonbiondo/call-log

  • Thanks for the code. This solves my problem and I'll accept it in a few days unless someone give us the some sort of "current-function-name" variable that is part of the debugger you hint at. – phs Oct 18 '14 at 7:38
  • By the way, it does not seem to work when a defun is enclosed by eval-and-compile, i.e. it returns nil. – Alexander Shukaev Dec 9 '18 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.