common-lisp - 以编程方式生成符号宏
问题描述
我有一个由两部分组成的数据结构:
- 将符号映射到索引的哈希表
- 包含数据的向量的向量
例如:
(defparameter *h* (make-hash-table))
(setf (gethash 'a *h*) 0)
(setf (gethash 'b *h*) 1)
(setf (gethash 'c *h*) 2)
(defparameter *v-of-v* #(#(1 2 3 4) ;vector a
#(5 6 7 8) ;vector b
#(9 10 11 12))) ;vector c
我想定义一个符号宏来获取向量a
而不通过哈希图。在 REPL:
(define-symbol-macro a (aref *v-of-v* 0))
工作正常:
* a
#(1 2 3 4)
但可能有很多命名向量,我不知道映射会提前是什么,所以我需要自动化这个过程:
(defun do-all-names ()
(maphash #'(lambda (key index)
(define-symbol-macro key (aref *v-of-v* index)))
*h*))
但这无济于事。而且我尝试过的任何组合都没有,例如将所有名称设为宏、反引号/逗号模板等。我开始怀疑这是否与它define-symbol-macro
本身无关。这似乎是一个很少使用的功能,On Lisp 只提到了两次。这里和其他地方都没有太多提及。在这种情况下,我使用的是 SBCL 2.1
有人有想法么?
解决方案
您需要像上面那样在运行时执行此操作:
(defun do-all-names ()
(maphash #'(lambda (key index)
(eval `(define-symbol-macro ,key (aref *v-of-v* ,index)))
*h*))
DEFINE-SYMBOL-MACRO
是一个宏并且不会计算它的所有参数。因此,您需要为每个参数对生成一个新的宏形式并对其进行评估。
另一种方法,通常在编译时,是编写一个在顶层生成这些表单的宏:
(progn
(define-symbol-macro a (aref *v-of-v* 0))
(define-symbol-macro b (aref *v-of-v* 1))
; ....
)
推荐阅读
- windows - 是否可以使用具有与管理员相同的浏览器数据的 RDP?
- c# - 如何在 UWP 中更改 AppBarButton 字体大小?
- sql-server - 如何转换具有层次结构的表?
- android - 在 Kotlin 中单击按钮将活动旋转 180 度
- javascript - Windows机器中未更新环境变量
- python - 更改绘图中的颜色范围(imshow)?
- flask - 从谷歌表单优化数据挖掘以用于推荐系统的在线统计(Heroku 上的 Flask 应用程序)
- r - 如何将简单的 Excel LOOKUP 转换为 R 代码?
- python - 如何在熊猫数据框中手动排列行
- python - Pool(num_cores) 因 PermissionError 崩溃:[WinError 5] 访问被拒绝