It is difficult to find an appropriate title because I do not understand why I have the following issue.
When I require
my package, I would like to assign a specific function according to some packages. The idea is to set a variable as follow:
(cond ((find-package 'foo) (setf *special-function* #'foo:foo-function))
((find-package 'bar) (setf *special-function* #'bar:bar-function))
(t (warn "The package FOO or BAR is required to enable the special function.")))
Then, the evaluation of this piece of code returns:
There is no package named "FOO"
with CCL
Package FOO does not exist
with SBCL
The main reason I want to do that is that it exists different packages which provide the same function, and I want to let the user be free to make its own choice by loading the package FOO or BAR (with a preference according to the order in the condition clauses).
Think about the execution/evaluation of the following form:
(if (find-package 'foo)
(foo:foo-function))
Lisp
Your error happens in phase 1: Reading. The form can't be read, when the package does not exist.
A typical way around it would be this:
(if (find-package 'foo)
(funcall (find-symbol "FOO-FUNCTION" "FOO")))
We are then looking up the symbol at runtime. Note that function and package names are by default in uppercase.
In your case you would need to call
(symbol-function (find-symbol "FOO-FUNCTION" "FOO"))
to get the function object. Note though that sometimes it's preferred to just get the symbol.
funcall
and apply
can call global functions as function object or as symbol:
(funcall 'sin 2.1d0)
or
(funcall #'sin 2.1d0)
Thus when the thing needs to be called later, a symbol offers another source of indirection and will point to the current definition, where the function object can also be an older version of the function.