Question

I need to programmatically call a macro which is similar to defun, in order to define a function of a given (auto-generated) name. My attempt is this:

`(defun ,(intern "autogen-command-33") () (echo "autogen-command-33!"))

However, for some reason, (intern ...) stopped working as expected (it now complains like this):

invalid number of arguments: 1
   [Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "worker" RUNNING {10078C8DE3}>)

Backtrace:
  0: [error printing frame]
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (INTERN "autogen-command-34") #<NULL-LEXENV>)
  2: (EVAL (INTERN "autogen-command-34"))

So I replace intern with make-symbol, which gives no error. Then, I attempt (autogen-command-35), expecting that it has been defined, but it hasn't:

STUMPWM> (eval `(defun ,(make-symbol "autogen-command-35") () (echo "autogen 35")))
#:|autogen-command-35|
STUMPWM> (autogen-command-35)
; Evaluation aborted on #<UNDEFINED-FUNCTION AUTOGEN-COMMAND-35 {10082F8D43}>.
STUMPWM> 

How do I programmatically define a named function in common lisp?

Was it helpful?

Solution

If you create a symbol as the name of a function you want to call, there are a few things to consider:

  • symbol names are uppercase internally, by default. So best create a symbol in the current case, typically uppercase.

  • symbols of functions usually should be in a package. INTERN is the function for that. INTERN the symbol in the right package. Best to specify the package when calling INTERN. See the documentation of INTERN.

Your symbol names were lowercase. MAKE-SYMBOL also just creates a symbol, but it is not interned in a package.

FOO> (INTERN "BAOBAB" "CL-USER")
COMMON-LISP-USER::BAOBAB
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top