[pro] why :key arguments?

Pascal J. Bourguignon pjb at informatimago.com
Mon Jul 4 16:42:14 UTC 2011


Nikodemus Siivola <nikodemus at random-state.net>
writes:

> On 4 July 2011 16:11, Alessio Stalla <alessiostalla at gmail.com> wrote:
>> On Mon, Jul 4, 2011 at 3:09 PM, Pascal J. Bourguignon
>> <pjb at informatimago.com> wrote:
>>> Nikodemus Siivola <nikodemus at random-state.net>
>>> writes:
>>>
>>>> On 4 July 2011 14:46, Stas Boukarev <stassats at 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 {}.





More information about the pro mailing list