Does (function) use any purpose in Emacs?

From the documentation of the function form:

Like quote, but preferable for objects that are functions. In byte compilation, the function function calls the compilation of its argument. quote cannot do this.

Thus, one could make #'(lambda ...) to enable byte compilation of the lambda form.

On the other hand, as indicated in the manual , this is no longer necessary.

The lambda form has another effect: it tells the Emacs expert and the byte compiler that its argument is a function, using function as a subroutine.
[...] The following forms are equivalent:

 (lambda (x) (* xx)) (function (lambda (x) (* xx))) #'(lambda (x) (* xx)) 

In this case, the form of the function is useless.

Is there any other situation where the form of the function would be useful?
Is there a case where his presence is neither superfluous nor identical quote ?

+6
source share
3 answers

#' (aka function ) is used internally by lambda , since lambda is defined as a macro that wraps in function . But other than that, you can actually write almost any Elisp code without using #' . There is another subtlety: tho: if you write #'foo , you will tell Emacs that you think foo is the name of the function, so the latest versions of the byte compiler will warn you if foo not a known function (just like they warned of calls to (foo ...) for many years).

As @Bruce pointed out, using #'foo instead of 'foo also makes a real difference for functions defined locally via cl-flet or cl-labels : in this case #'foo is locally defined, and 'foo will just refer to the character foo , which is not actually related to the definition of a local function and, therefore, can be unbound or bound to another function:

 (cl-flet ((a () 1)) (list 'a (functionp 'a) #'a)) 

returns

 (a nil (lambda nil 1)) 
+12
source

lambda is a macro. It must expand and expand every time. Like this:

 (lambda (x) x) -> (function (lambda (x) x)) ; #'(lambda (x) x) 

function is a special operator. In fact, it processes lambda forms on purpose, otherwise we can never extend the lambda macro:

 (lambda (x) x) -> (function (lambda (x) x)) -> (function (function (lambda (x) x))) -> ... 

function looks at its argument, and if it is a lambda form, it compiles this function. If its argument is a character, it searches for a compiled function associated with the character.

So now we see that function (e.g. quote ) does not evaluate its argument. It must have special behavior, so it is a special operator.

+4
source

Thus, one could make #'(lambda ...) to enable byte compilation of the lambda form.

On the other hand, as mentioned in the manual, this is no longer necessary.

The programmer no longer needs to write (function (lambda ...)) (or the abbreviated # '(lambda ...) , because (lambda ...) expands to (function (lambda ...)) . Other answers explained this very good. First, give the documentation for the function:

From the documentation of the function form:

Like quote , but preferable for objects that are functions. In byte compilation, function compiles its argument. quote cannot do this.

Therefore, the function documentation does not address the difference between

  • (function (lambda …)) and
  • (lambda …)

but between

  • (quote (lambda …)) and
  • (function (lambda …)) .

In most modern Lisps (Common Lisp, Scheme, etc.) a form (quote (lambda ...)) or just (lambda ...)) is just a list, and this is not something that can be called up. For example, in SBCL:

 * (funcall '(lambda () 42)) ; debugger invoked on a TYPE-ERROR in thread #<THREAD "initial thread" RUNNING {1002978E71}>: ; The value (LAMBDA () 42) is not of type (OR FUNCTION SYMBOL). 

However, in Emacs Lisp you can call the list:

 (funcall '(lambda () 42)) ;=> 42 

In the question of whether the function serves any purpose, we must ask "what can we do without it" or "what is its alternative?" We cannot answer that “we will just write (lambda ...) ” because, as others have pointed out, it simply expands to (function (lambda ...)) . If we do not have a function , we can still use quote . We can still write a lambda macro that extends to (quote (lambda ...)) and thus writes (funcall (lambda ...)) , and the code will look the same. The question is, "what's the difference?" The difference is that in the quote version we transfer literal lists, and they cannot be compiled for functions, because we still need to be able to do similar things with them (for example, take a car and cdr ). The function is useful here, regardless of whether we write it ourselves or depend on the macro to use it in the extension. This makes it possible to write function objects instead of lists.

+4
source

Source: https://habr.com/ru/post/973734/


All Articles