将Common Lisp中的宏参数视为(区分大小写)字符串

时间:2012-02-19 08:37:17

标签: string common-lisp symbols case-sensitive

(这是其中一个似乎应该如此简单的事情,我想可能会有一个更好的方法)

我试图定义一个宏(对于CLISP),它接受可变数量的参数作为符号(然后将其转换为区分大小写的字符串)。

(defmacro symbols-to-words (&body body)
  `(join-words (mapcar #'symbol-name '(,@body))))

将符号转换为大写字符串,而

(defmacro symbols-to-words (&body body)
  `(join-words (mapcar #'symbol-name '(|,@body|))))

将@ body视为单个符号,没有扩展。

有什么想法吗?我认为这可能是一个更容易的方式。

2 个答案:

答案 0 :(得分:6)

符号名称在读取器步骤期间是大写的,这在宏展开之前发生,因此没有什么可以用宏来影响它。您可以全局设置READTABLE-CASE,但这会影响所有代码,特别是您必须在源代码中以大写形式编写所有标准符号。 CLISP还有一个“-modern”选项,它为标准库的名称提供了小写版本,并将读者设置为保留大小写,但它本身是非标准的。我自己从未使用过它,所以我不确定实际应用的注意事项。

控制阅读器的另一种方法是通过阅读器宏。 Common Lisp已经有一个读取器宏,它实现了区分大小写的字符串的语法:double quote。如果不知道为什么不仅仅使用它,很难提供更多的建议。

答案 1 :(得分:3)

正如Ramarren所说,符号的情况是在读取时间内确定的。不是在宏观扩张时。

Common Lisp有一种语法,用于指定符号而不改变大小写:

|This is a symbol| - 使用竖线作为多个转义字符。

并且还有一个反斜杠 - 一个转义字符:

CL-USER > 'foo\bar
|FOObAR|

其他选项包括:

  • 使用不同的全局可读案例
  • 使用读取和保留大小写的读取宏
  • 使用使用自己的阅读器的阅读宏

另请注意,Common Lisp中不存在类似|,@body|(其中绑定了body)的语法。拼接仅适用于列表 - 而不是符号名称。垂直条|包围符号的字符元素。 Common Lisp Hyperspec中的解释有点神秘:Multiple Escape Characters