All of the compilation of that file happens before executing any of the load-op
s. So when Lisp compiles the (sdl-examples:squashed)
line, it hasn't run the load-op
that defines your package.
You can get around this by not mentioning the sdl-examples
package that requires the reader to locate its squashed
symbol before the load-op
is actually executed:
(funcall (symbol-function (intern (symbol-name '#:squashed)
(find-package (symbol-name '#:sdl-examples)))))
The idea is to calculate the package from its symbolic name, lookup the symbol naming your function, and fetch the function it names - but this way requires that the package exist only when the code is run, not when it is first read. Then your four statements can all be compiled, executed in order, and by the time that last statement is executed, your load-op
s will have created the package.
So here's a little more info about what's happening here:
- Writing
'#:some-name
refers to a symbol that's not part of any package. So that way we can make a reference to a symbolic name without either (1) assuming its package exists or (2) mucking up some other package with the name.
- Then
'(symbol-name #:some-name)
extracts the name of the symbol as a string. Why not just write "some-name"
? You could, and it will usually work. But this way is a little more robust for the case of running a "modern-mode" case-sensitive Lisp.
- The
find-package
maps a string name to Lisp's representation of a package. Remember, by the time you run this line, your package will exist.
intern
returns the symbol with the given name that lives in the given package.
symbol-function
returns the function object (a lambda abstraction, or more likely, its compiled representation) associated with the symbol.
- And then
funcall
invokes that function.
It is kind of clunky, but unfortunately there's not really a better way to mix calls which load code to create a package with names living in that package in the same file.