尝试编写一个在常见的lisp中创建全局符号的函数

时间:2018-01-18 22:26:48

标签: common-lisp

我有一个全局的单词(符号)列表,我想写一个可以添加新单词的函数。我可以添加新单词,但后来我遇到了它们未绑定的错误。我该怎么写函数:

(defun add-symbol (aNewWord) (... ))

让它创建一个全局符号 使用我输入的参数作为名称?

也许我希望用户在运行时添加新符号。

2 个答案:

答案 0 :(得分:3)

使用PUSH将元素添加到列表中。

(defvar *word-list* ())

(defun add-symbol (new-word)
  (push new-word *word-list*))

(add-symbol 'hello)
(add-symbol 'friday)
*word-list*

输出是:

(FRIDAY HELLO)

如果您收到有关未绑定变量的错误,则在将它们用作函数的参数时,可能会忘记引用这些符号。如果您没有引用符号,则将其视为变量名称并尝试使用其值。

答案 1 :(得分:1)

通常,您希望控制用户创建的数据的命名空间,而不是将其泄漏到您的程序结构中。因此,最好创建一些(可能是顶级)数据结构,在其中保存数据。 从用户数据创建变量。

此类数据的密钥可能是符号,您可以使用intern创建这些符号。如果要创建具有用户指定名称的新符号,可能需要使用关键字package:

(defun make-user-symbol (string)
  (intern string '#:keyword))

或一些原始包装正是这些符号:

(defpackage #:user-symbols)

(defun make-user-symbol (string)
  (intern string '#:user-symbols))

这种事情的一个灵活的数据结构是哈希表:

(defvar *user-data* (make-hash-table :test #'eq))

(defun add-user-data (keystring value)
  (setf (gethash (make-user-symbol keystring) *user-data*)
        value))

当然,您也可以使用字符串,但哈希表需要使用:test #'equal

如果你想将一组单词作为符号(虽然我认为不需要这样的转换),你的数据结构可能是一个列表:

(defvar *words* ())

(defun add-word (string)
  (push (make-user-symbol string) *words*))