1

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?

4
  • (eval (defun ,(intern "autogen-command-33") () (echo "autogen-command-33!")))` works for me in SBCL. What is your *package*? can you try the same in xterm instead of slime? Commented Apr 28, 2014 at 21:15
  • apparently I had messed something and intern wasn't working correctly. It did eventually work as you and I would expect Commented Apr 28, 2014 at 21:57
  • General advice: it is often not a good idea to do something like this. It can become unnecessarily hard to understand a program where you cannot find the place a specific function was defined. Commented Apr 7, 2016 at 20:10
  • in this case my goal was really to use the "defcommand" macro of stumpwm, to auto-define a number of simple commands (eg make a certain keypress) that were specified declaratively in a config file, and I try to make it clear these are autogenerated (eg auto-... prefix and docstring) but I agree for normal functions it is best to avoid this Commented Apr 7, 2016 at 22:17

1 Answer 1

2

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 
Sign up to request clarification or add additional context in comments.

2 Comments

for some reason I get invalid number of arguments for (INTERN "BAOBAB" "CL-USER")
thanks. something was wrong with my intern function. the upper-case tip helped.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.