Nikodemus Siivola <nikodemus@random-state.net> writes:
On 4 July 2011 16:11, Alessio Stalla <alessiostalla@gmail.com> wrote:
On Mon, Jul 4, 2011 at 3:09 PM, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
Nikodemus Siivola <nikodemus@random-state.net> writes:
On 4 July 2011 14:46, Stas Boukarev <stassats@gmail.com> wrote:
* They can't be used with APPLY or FUNCALL.
Actually, they can be used with FUNCALL.
(Otherwise, I echo pretty much everything that Stas said.)
clhs define-compiler-macro: "The consequences of writing a compiler macro definition for a function in the COMMON-LISP package are undefined;"
You, the user, can't, but Nikodemus, the implementer, can! ;)
There's a misunderstanding here. I didn't mean -- nor do I think Stas meant -- writing a compiler-macro for APPLY or FUNCALL, but rather having a compiler-macro take effect when the function in question is called using FUNCALL or APPLY:
(apply #'has-a-compiler-macro ...) ; compiler-macro will not fire
(funcall #'has-a-compiler-macro ...) ; compiler-macro should (if supported) fire
I don't think so. First you're discussing here of a (function f), not (quote f), and COMPILER-MACRO-FUNCTION takes a function name, not a function or function designator. So even if the compiler did the optimization of avoiding the call to CL:FUNCALL, it could still have difficulty and scruples of building a source form from a function object. But even if we considered: (funcall (quote has-a-compiler-macro) args...) the compiler just could not call the compiler macro of that function name, for this reason: (defun f (args...) (do-something args...)) (define-compiler-macro f (&environment env &whole form args...) (if (special-f-case-p env form) (generate-special-f-form env form args...) form)) (flet ((f (args...) (do-something-else args...))) (funcall (quote f) args...)) The funcall doesn't refer the same function as if we had written: (f args...) and therefore we cannot pass that form to the compiler macro, because it doesn't correspond to the function of the compiler macro! [The case of (function f) is even more telling in this case: (flet ((f (args...) (do-something-else args...))) (funcall (function f) args...)) since in that case, the function denoted has no compiler macro!] And even if the implementation supports compiler macros, there's no reason it should implement the optimization of avoiding the call to funcall. Therefore: 1- compiler macros won't apply when the function is called by FUNCALL as well as when it's called by APPLY. 2- in my opinion, even in presence of a highly optimizing compiler, synthesizing source code for the benefit of macros or compiler macros would be a bad idea and rarely applicable without problems. -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}.