0

In order to understand what the symbol funcall means I have checked out its documentation. If I understand it right after reading the docs this symbol represents a function which in my eyes can be always easily removed from the elisp expression without changing the outcome:

(funcall '+ 1 2) ; returns 3
(+ 1 2)          ; returns 3

Also in the code example provided in the funcall function documentation the expression works OK after skipping funcall from it:

(funcall 'cons 'x 'y) ;returns (x . y)
(cons 'x 'y)          ;returns (x . y)

What is the difference between the two code versions giving funcall the right to exist?

Is it just for fun there in order to be able to obfuscate:

(+ 3 2)

expressing it as:

(defun 3+ (x) (+ x 3)) (3+ 2)
(funcall (lambda (x) (+ x 3)) 2)
;; with finally: 
(funcall (setq 3+ (lambda (x) (+ x 3))) 2)

?

Or is it there to fix the problem if someone erroneously misused the value slot of a symbol to store there a function?

In other words: is there a code example able to demonstrate a meaningful usage of funcall?


@Drew : elisp is able to distinguish between the value and the function "slots" of a symbol without usage of funcall from the context of symbols usage. Run following piece of code in Emacs 29 to see it yourself:

(setq  f    2)
(defun f () 3)
(message "val: %s  func: %s  symb: %s" f (f) 'f)

which gives:

"val: 2  func: 3  symb: f"

@Drew : to my knowledge in elisp ALL symbols and expressions are ALWAYS evaluated. Also 'f becomes evaluated and it equals to f only because ' is a syntactical sugar for a special form quote returning f as the value of to it passed parameter without evaluating it.

Claudio
  • 410
  • 2
  • 11
  • `funcall` is a function, which in Lisp means that all of its args are evaluated. Consider that you can pass a variable whose value is a function to a `funcall` sexp. That sexp can then invoke whatever function is the variable's value. You can, e.g., use `funcall` in a higher-order function that takes a function as one of its arguments, and that invokes that function. This is how higher-order functions such as `mapcar` work. – Drew Apr 17 '23 at 01:53
  • 1
    I really suggest you read about Lisp a bit. Maybe read the manual [Introduction to Programming in Emacs Lisp](https://www.gnu.org/software/emacs/manual/eintr.html), which is provided with Emacs (`C-h i`). – Drew Apr 17 '23 at 01:53
  • There are 2 kinds of Lisp: Lisp-1 and Lisp-2. Scheme is Lisp-1; Elisp is Lisp-2. With Lisp-1 you can write `(a 42)` to evaluate variable `a` to get a function and then invoke that function with argument 42. With Lisp-2 you cannot. Instead you have to write `(funcall a 42)` to accomplish the same thing. This is because in a Lisp-2 a symbol such as `a` can have a value as a variable (that value could of course be a function) **and** a completely different "value" as a function. `(symbol-value 'a)` gives the value of symbol `a` as a variable. `(symbol-function 'a)` gives its value as a function. – Drew Apr 17 '23 at 01:59
  • 2
    Again, don't try to learn about this just from some comments here. Read a bit about Lisp. That's a suggestion. – Drew Apr 17 '23 at 02:01
  • @Drew : if I were successful in finding a meaningful example of code, I won't ask that question. A link to appropriate piece of code demonstrating a case which would be hard to rewrite without `funcall` would be enough. Not every command/instruction/function/keyword in a programming language is for actual meaningful usage there - some are just for the sake of some kind of completeness. – Claudio Apr 17 '23 at 02:16
  • @Drew : see the update to my question. You write *Elisp is Lisp-2 and in Lisp-2 you need `(funcall a 42)`* It's not true for me. Just run the example I gave in the update to see it yourself. – Claudio Apr 17 '23 at 02:35
  • 1
    *Of course* Emacs Lisp can distinguish between the value cell and the function cell of a symbol. The question is how to call a function that is stored in the *value* cell of a symbol: it's for that you need `funcall`. Why you would want to store a function in the value cell of a symbol? See my answer for a "real" example. – NickD Apr 17 '23 at 04:02
  • 2
    Do NOT write: `((lambda (...) ...) ...)`, see [10.2.4](https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Indirection.html): “*This form is rarely used and is now deprecated.*” – shynur Apr 17 '23 at 07:09
  • The answer to [this question](https://emacs.stackexchange.com/questions/59204/how-to-call-a-function-that-is-the-value-of-a-variable) might be helpful. – NickD Apr 17 '23 at 16:43
  • To invoke a function that is the value of a variable, given only that variable, you need to use `funcall` (or `apply` or etc.). The point is that you cannot just put the variable in the car of a list and then evaluate that list. With Lisp-2, the car of a list that's evaluated is *not* evaluated as a variable. Instead, the `symbol-function` value of that symbol is used as the function to invoke. IOW, you can't just use `(f arg1...)` to invoke the function that's the value of variable `f` on the args. This is the difference between Lisp-1 and Lisp-2. – Drew Apr 17 '23 at 23:16
  • *"code demonstrating a case.."* Look for a definition of any higher-order function that accepts a function as an argument. Look for a `mapcar` definition in Lisp, for example (it's very simple. You really need to look around a bit, IMO. Do yourself a favor and open the Into to Elisp manual... – Drew Apr 17 '23 at 23:18
  • Yes, you are right with *IMO*. It's your opinion. – Claudio Apr 17 '23 at 23:33

3 Answers3

1

Virtually all of the "real" examples are variations of the following theme: you have a list of functions and you want to call each function in turn (e.g. hooks are lists of functions - when the hook is run, we march down the list and call each function in turn). You cannot march down the list with car and cdr and for each element call it. E.g. this does not work:

;; make a list of a couple of functions
(setq my-hook nil)
(add-hook 'my-hook (lambda () (message "foo")))
(add-hook 'my-hook (lambda () (message "bar")))

;; march down the list, calling each function in turn
(dolist (element my-hook) (element))
==> Debugger entered--Lisp error: (void-function element)
  (element)
  (let ((element (car tail))) (element) (setq tail (cdr tail)))
  (while tail (let ((element (car tail))) (element) (setq tail (cdr tail))))
  (let ((tail my-hook)) (while tail (let ((element (car tail))) (element) (setq tail (cdr tail)))))
  (progn (let ((tail my-hook)) (while tail (let ((element (car tail))) (element) (setq tail (cdr tail))))))
  eval((progn (let ((tail my-hook)) (while tail (let ((element (car tail))) (element) (setq tail (cdr tail)))))) t)

element is bound to each element of the list in turn, but through its value cell, not its function cell, so you cannot call it as a function any more than you can do:

(setq foo (lambda () (message "foobar")))
(foo) ==>  
Debugger entered--Lisp error: (void-function foo)
  (foo)

But you can funcall it:

(funcall foo) ==> nil ;; i.e. no error

Similarly for the my-hook list of functions, you can do:


(dolist (element my-hook) (funcall element))

In both cases, you can check *Messages* to see that the functions were indeed called (and in the correct order in the case of the list).

As I said, this is how hooks are run. There are complications of course, which is why simple examples are used to get the concepts across before you have to worry about all the additional wrinkles that have to be ironed out with real hooks.

NickD
  • 27,023
  • 3
  • 23
  • 42
0

Symbols can't just hold a value (as variables). Symbols can also hold a function definition (see Symbol Components). That is, a symbol can act as both a variable and a function.

funcall just calls the function definition stored in a symbol.

A real example from my repo: org-shoplist is a testing-function:

(defun org-shoplist-test-test-in-buffer (func-in-buffer)
  (org-shoplist-test-test
   (lambda ()
     (unwind-protect
         (with-current-buffer (get-buffer-create org-shoplist-test-default-buffer)
           (funcall func-in-buffer)) ;; <--- function called which is stored in the arguemnt
       (kill-buffer org-shoplist-test-default-buffer)))))

This function executes a test in temp-buffer and leaves everything in same state as before. ‘FUNC-IN-BUFFER’ is what should be done in the temp-buffer.

Concrete call of this function would look like this:

(ert-deftest org-shoplist-test/recipe-read-one-ing ()
  (org-shoplist-test-test-in-buffer
   (lambda ()
     (setq org-shoplist-inital-factor nil)
     (insert "* Test
- (200g Nuts) mahlen")
     (goto-char (point-min))
     (should (equal (list "Test" nil 'org-shoplist--recipe-read-ings-current
                          (list (org-shoplist-ing-create "200g" "Nuts")))
            (org-shoplist-recipe-read 'org-shoplist--recipe-read-ings-current))))))

I pass a concrete function (the test-case) into another more general function (which has the funcall-call). funcall helps writing lesser code, because I can extract the general parts and pass in the concrete ones by argument.

Drew
  • 75,699
  • 9
  • 109
  • 225
lordnik22
  • 121
  • 7
  • Hmmm ... What is `func-in-buffer`? Is it what I suggested to be "erroneously misusing a value slot for storing a function"? At the first glance the code looks for me like an obfuscated (+ 3 2) or result of a confusion of its programmer. Sorry ... it's to complex for me - I have no idea what org mode is for too having same problems to see a meaningful example of its usage. – Claudio Apr 17 '23 at 01:40
  • Hi Claudio, I added a concret test-case to illustrate my example a bit more. Beaware that a symbol has 2 slots. One for values, and one for function definition. Why is it wrong to store a function definition in a symbol? – lordnik22 Apr 17 '23 at 01:56
  • Nothing wrong with storing a function in the function slot of a symbol. But storing a function in the value slot in spite of the fact that it's possible doesn't make sense to me. And yes, I am aware that symbols can store functions and values. But storing functions in a symbol using `(setq` instead of `(defun` does not make much sense. The "finally" line of the obfuscated code in my question uses `funcall` exactly for the "purpose" of running a function which was stored as a value. – Claudio Apr 17 '23 at 02:07
  • Funny:: "200g Nuts", but "mahlen" not "grind" :) or ... "Nuts" instead of "Nüsse" :) – Claudio Apr 17 '23 at 02:11
  • I have checked out the code in your repo. For example you don't need the `funcall` in `(funcall #'org-mode)` which makes it only an obfuscated way of coding `(org-mode)`. Anyway the `org-mode` symbol does not have a value, so it does not make sense to indicate explicit that you use it's function cell either. I suggest you reconsider your coding style getting rid of `funcall` in cases it is unnecessary polluting the code. – Claudio Apr 17 '23 at 11:16
0

Let's consider the case that you have plenty of functions in your Emacs initialization file to which you pass 1 as parameter:

(desktop-save-mode 1)
;; ... many other functions ...
(show-paren-mode   1) 

Now you want to avoid repetition of the parameter value 1 and the calls replacing the above with only one function call to which you pass a list of functions taking this parameter. The code which accomplishes this would be hard to write without using funcall:

;; Run multiple functions with the same passed to them parameter
(mapcar (lambda (f) (funcall f 1)) '(
    desktop-save-mode 
;; ... many other functions ...
    show-paren-mode
))

because in this kind of code design elisp is somehow not able to recognize from the context that f will represent a symbol storing a function and must be instructed with funcall in order not to fail with the message: "Symbol’s function definition is void: f" while running the code.

As explained in the answer by NickD the "somehow not able" is caused by the elisp mechanism of taking items from a list of items in order to provide them as item symbol to the item processing code block.

This mechanism is not capable of recognizing the context and therefore does not differentiate between list symbols representing functions and list symbols representing values. In other words this mechanism provides the list items just always in a value cell instead of the function cell in case the list items are functions. The consequence of this fact is the necessity of using funcall to avoid elisp runtime errors.

Claudio
  • 410
  • 2
  • 11