测试符号是否是宏中的哈希表

时间:2016-03-10 20:09:22

标签: macros common-lisp

我想根据作为参数提供的符号类型构建一个扩展为不同形式的宏。一个小的可重现的例子(其中两个,实际上......在sbcl和ccl上失败)如下:

λ (defmacro what-am-i (a-thing)
   (etypecase a-thing
        (list         `(format t "im a list"))
        (vector       `(format t "im a vector"))
        (hash-table   `(format t "im a hash-table"))))

λ (defmacro what-am-i2 (a-thing)
     (cond
        ((typep a-thing 'list)         `(format t "im a list"))
        ((typep a-thing 'vector)       `(format t "im a vector"))
        ((typep a-thing 'hash-table)   `(format t "im a hash-table"))))

λ (what-am-i '(1 2 3 4))
im a list
NIL

λ (what-am-i "abcd")
im a vector
NIL

λ (what-am-i *my-hash*)

debugger invoked on a SB-KERNEL:CASE-FAILURE in thread
#<THREAD "main thread" RUNNING {10039846F3}>:
  *MY-HASH* fell through ETYPECASE expression.
  Wanted one of (LIST VECTOR HASH-TABLE).

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-KERNEL:CASE-FAILURE ETYPECASE *MY-HASH* (LIST VECTOR HASH-TABLE))
0] ^D

λ (what-am-i2 '(1 2 3 4))
im a list
NIL

λ (what-am-i2 "abcd")
im a vector
NIL

λ (what-am-i2 *my-hash*)

NIL
λ (typep *my-hash* 'hash-table)

T

有谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:6)

符号的类型始终为symbol: - )

在代码执行(已评估)之前,不知道符号的的类型。

因此,(what-am-i '(1 2 3 4))会看到一个列表(quote (1 2 3 4))并报告它是一个列表,而(what-am-i *my-hash*)会看到一个符号*my-hash*并报告错误。

您可以使用symbol-value在宏扩展时访问该符号的全局值,但我怀疑您在这里提出了错误的问题。

我建议您提出一个单独的问题,解释您实际上想要实现的目标。