以编程方式定义具有给定名称的函数

时间:2014-04-28 18:01:07

标签: lisp common-lisp

我需要以编程方式调用一个类似于defun的宏,以便定义给定(自动生成)名称的函数。我的尝试是这样的:

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

但是,出于某种原因,(intern ...)停止按预期工作(它现在抱怨这样):

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"))

所以我将intern替换为make-symbol,这不会出错。然后,我尝试(autogen-command-35),期望它已被定义,但它没有:

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> 

如何以编程方式在常见的lisp中定义命名函数?

1 个答案:

答案 0 :(得分:2)

如果您创建一个符号作为您要调用的函数的名称,则需要考虑以下几点:

  • 默认情况下,符号名称在内部为大写。因此,最好在当前案例中创建一个符号,通常为大写。

  • 函数的符号通常应该在一个包中。 INTERN就是这个功能。 INTERN右包装中的符号。最好在调用INTERN时指定包。请参阅INTERN

  • 的文档

您的符号名称是小写的。 MAKE-SYMBOL也只是创建一个符号,但它不是封装在一个包中。

FOO> (INTERN "BAOBAB" "CL-USER")
COMMON-LISP-USER::BAOBAB