【发布时间】:2011-12-25 12:21:40
【问题描述】:
我正在尝试在reading 时构建一个哈希表(以及其他操作)。我不希望哈希表具有全局范围(还),所以我使用宏和gensym 来执行此操作。在宏x 中,我定义了一个宏s,它类似于setf,但在哈希表中定义了一个条目,而不是在某处定义符号。它爆炸了。我想我理解错误消息,但我该如何让它工作?
代码:
#!/usr/bin/clisp -repl
(defmacro x (&rest statements)
(let ((config-variables (gensym)))
`(macrolet ((s (place value)
(setf (gethash 'place ,config-variables) value)))
(let ((,config-variables (make-hash-table :test #'eq)))
(progn ,@statements)
,config-variables))))
(defun load-config ()
(let ((config-file-tree (read *standard-input*)))
(eval config-file-tree)))
(defun load-test-config ()
(with-input-from-string (*standard-input* "(x (s fred 3) (s barney 5))")
(load-config)))
(load-test-config)
输出:
*** - LET*: variable #:G12655 has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of #:G12655.
STORE-VALUE :R2 Input a new value for #:G12655.
SKIP :R3 skip (LOAD-TEST-CONFIG)
STOP :R4 stop loading file /u/asterisk/semicolon/build.l/stackoverflow-semi
【问题讨论】:
-
这看起来很复杂,我敢打赌你不需要任何东西。宏,macrolet,读取数据的 EVALuation,单字母宏名称,...
-
通常我会同意:它太复杂了。但这是更复杂的事情的一部分。我把它提炼成一口大小的情况,使问题更容易提出。
-
为什么要将哈希表编码为 Lisp 源代码?
-
如果它只是一个静态哈希表,我不会。此哈希表中的某些值将是 lambda 表达式,在 eval 长时间完成后的某个时间点,可能会调用它们来设置(例如)fred 的值。
标签: lisp common-lisp clisp gnu-common-lisp