help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to quote a list of functions?


From: Pascal J. Bourguignon
Subject: Re: How to quote a list of functions?
Date: Sun, 09 Aug 2015 02:30:23 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Marcin Borkowski <address@hidden> writes:

> It is well known that functions should be quoted with sharp-quote and
> not just regular quote, i.e., #'my-function and not 'my-function.  

That's where you are wrong.  Thrice in a single sentence!

1- sharp-quote doesn't quote functions.

2- sharp-quote, ie. function is a special operator (special form in
   emacs lisp) that takes NOT a function, but a FUNCTION NAME, and
   returns the function named by that NAME found in the lexical
   environment in CL, BUT returns the FUNCTION NAME in emacs lisp!

      (function f) --> f
      #'f          --> f
   
   Therefore there is absolutely no difference in emacs lisp between
   quote and function, when passed function names, or when interpreted.

   The difference, in emacs lisp, is when you compile a lambda form.
   In emacs lisp a lambda form IS a function:

       (functionp '(lambda (x) x)) --> t

   But if you quote a lambda form, then the compiler will take it for
   data, and leave it alone, and you'll get your anonymous function not
   compiled.  Instead, Using (lambda (x) x) will macroexpand to 
   (function (lambda (x) x)) and the compiler will know that the lambda
   form is code, and will compile it.  In the interpreter that doesn't
   change a thing, since function is still just like quote:

     (function (lambda (x) x)) --> (lambda (x) x)
   
   but if you compiled that form, you'd get a byte-code function object:

     (defun g () (function (lambda (x) x)))
     (g)               --> (lambda (x) x)   
     (byte-compile 'g) --> #[nil "\300\207" [#[(x) "\207" [x] 1]] 1]
     (g)               --> #[(x) "\207" [x] 1]

   Compare with:

     (defun h () (quote (lambda (x) x)))
     (byte-compile 'h) --> #[nil "\300\207" [(lambda (x) x)] 1]
     (h)               --> (lambda (x) x)

3- you can QUOTE function names, and should when you use function names
   as function designators for arguments to high order functions!

   The only thing, is that:

     1- in Common Lisp, you cannot designate local lexical functions
        with their function name: function names can only designate
        global functions.

            (defun f () 'global)

            (let ((f (flet ((f () 'local))
                       (list (function f)
                             (funcall (function f))
                             (funcall (quote f))))))
              (setf (car f) (funcall (car f)))
              f)
            --> (local local global)

     2- in emacs lisp, there are no local lexical functions, flet
        rebinds the global function name, and the function name always
        denote the current (dynamic) binding of the function.

            (setf lexical-binding t)
            (defun f () 'global)

            (let ((f (flet ((f () 'local))
                       (list (function f)
                             (funcall (function f))
                             (funcall (quote f))))))
              (setf (car f) (funcall (car f)))
              f)
            --> (global local local)



In conclusion:

   - no #' with lambda.

   - no ' with lambda.

   - in emacs lisp, #' and ' do the same on functio names (non lambda
     forms).
     
   - in Common Lisp, #' and ' on a function name without a local lexical
     function by that name designate the same global function, so you
     can use ' as well as #', and notably, any function in the CL
     package CANNOT be shadowed by a local lexical function binding,
     and therefore CAN always be designated with a quoted function name
     (the symbol naming the function).

   - in Common Lisp, when you have a local lexical function binding, #'
     with that function name will give you the local function, while '
     with that function name will designate the global
     function. Therefore you would use #' ONLY if you want to designate
     the local function! You MUST use ' if you want to designate the
     global function!




And of course, your problem is totally unrelated to your question.

> (setq custom-format #'((format-field-one 4) ...))

Here, you have a high order function, format-field-one that will return
a function object, when called.  Then you cannot use a literal list, you
must create the list at run-time, when you call format-field-one:

   (setq custom-format (list (format-field-one 4)))
or:
   (setq custom-format `(,(format-field-one 4)))


-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk


reply via email to

[Prev in Thread] Current Thread [Next in Thread]