3

Macros may create functions in the global scope. For example:

(defmacro test-macro (&body functions)
 `(progn ,@(loop for function in functions
               collect `(defun ,function ()
                           *some-interesting-thing*))))

Another example (albeit with methods) would be the automatically generated accessors for a CLOS class.

The functions are not defined at macro expansion time, but rather when the generated code is compiled/interpreted. This can cause some difficulty. If these functions are being expected, a warning will be thrown. What is the idiomatic way to define these functions before they are correctly defined? One potential solution might be the following:

(defmacro test-macro (&body functions)
  (macrolet ((empty-function (name)
                `(defun ,name ())))
    (dolist (function functions)
       (empty-function function)))
  `(progn ,@(loop for function in functions
                collect `(defun ,function ()
                            *some-interesting-thing*))))

Note that the intermediate function is defined during macro expansion time.

1
  • The problem you are describing (as I understand it) should not exist (as per the spec) and does not exist (in any implementation I know of). Could you please provide explicit code samples? Commented Mar 17, 2015 at 15:57

1 Answer 1

4

If you need to define a function at compile time on the toplevel, then use:

(eval-when (:compile-toplevel)
  (defun foo ...))

Note that you can define a macro which generates such code. Such a form can be part of a PROGN.

Sign up to request clarification or add additional context in comments.

2 Comments

In the majority of cases, if you use eval-when at the toplevel, you want all of (:compile-toplevel :load-toplevel :execute).
@Svante: I wouldn't say that. Common Lisp implementations use :compile-toplevel often for compile-time-only side effects. For example DEFUN notes the function at compile-time, but does not define it. Often that's a useful pattern to follow. Also eval-when makes only sense at the so-called toplevel. Other than that it has no real use. Note that 'toplevel' has a special meaning in the context of compilation and that forms inside a PROGN are still at 'toplevel'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.