Common Lisp: It is defined earlier in the file but is not available at compile-time

Experienced lisp programmers know the cause on the first glance of the error message. But someone who is just learning lisp like me might be confused. I tried google search the error first, but got nothing. So after I figured out it by myself, I thought it might be worth to write it down for somebody's reference in the future.

The issue

Put the following in 'test.lisp' and compile it:

(defun get-bindings ()
  `((a 1) (b 2)))

(defmacro testm ()
  `(let ,(get-bindings)
     (+ a b)))

(testm)

There will be an error :

ERROR: (during macroexpansion of (TESTM))
The function COMMON-LISP-USER::GET-BINDINGS is undefined.
It is defined earlier in the file but is not available at compile-time.

Note that the exact wording of the error might be different per lisp implementations.

The code compiles fine if the top-level form '(testm)' is removed. The problem here is that:

Possible solutions:

1. You can put all utility functions called during macro expansion time inside a '(eval-when (:compile-toplevel :load-toplevel :execute))' form. But this does not sound ideal - it somehow feels tricky, and it's easy to forget to include some utility functions.

2. Use system (asdf - but can also be other build systems which I don't know) to organize your code: put the macro definitions and all utility functions used by them in a separate file, and make sure all the files using these macros depend on it. For example:

(defsystem "hello-lisp"
  :description "hello-lisp: a sample Lisp system."
  :version "0.0.1"
  :author "Joe User "
  :licence "Public Domain"
  :depends-on ("optima.ppcre" "command-line-arguments")
  :components ((:file "packages")
               (:file "macros" :depends-on ("packages"))
               (:file "hello" :depends-on ("macros"))))

You need to define system anyway unless you are just experimenting some random code. In that case you can just evaluate all utility functions first.

[1] defun

[2] Processing of Top Level Forms

---------------------

Published on 2023-10-28

The content for this site is licensed under:

CC-BY-SA