【问题标题】:Creating a keyword symbol创建关键字符号
【发布时间】:2015-01-17 01:38:22
【问题描述】:

我正在尝试创建一个带有一些关键字参数的宏,并且只有在定义了参数的情况下,才将条目添加到列表中。将其拆分为以下代码应该说明我需要什么。

(defun add-if-not-null (var lst)
  (if (not (null var))
      (append (cons (***) (cons ver '())) lst)))

三个星号表示我要弄清楚的部分。这基本上采用符号名称并将其转换为关键字表示。例如宽度转换为 :width

(let ((width 100))
    (add-if-not-null (width '())))

应该返回

(:width 100)

我正在使用 cl-who 创建一个 svg 表示,并且基本上只想设置宽度和高度等属性,前提是它们被指定为包装文档的宏的参数。

【问题讨论】:

  • Common Lisp Programmatic Keyword 的可能重复项(注意您可以通过 (symbol-name 'width) 从符号 width 中获取字符串 "WIDTH")。
  • 这些都不符合我在下面提到的要求。我需要找到一种将变量/参数名称转换为关键字参数的方法。如果我需要将它转换为字符串,那很好。如果您查看示例,那么到目前为止的答案不会产生正确的解决方案。
  • 啊,我明白你的意思了。我过于关注“这基本上采用符号名称并将其转换为关键字表示”。问题是,编译后的代码中没有符号widthsource 中有一个词法变量,用符号width 表示。你需要一个宏来完成这项工作,但好消息是它并不太难。我认为 Rainer 的编辑适合您。
  • 绝对正确@Joshua Taylor。我说错了,我的问题需要更清楚。感谢您的反馈。

标签: lisp common-lisp symbols


【解决方案1】:

包的名称是KEYWORD。使用INTERN 创建符号(如有必要)并放入包中。

CL-USER 11 > (intern (symbol-name 'width) "KEYWORD")
:WIDTH

宏:

CL-USER 29 > (defmacro add-if-not-null (var list)
               (check-type var symbol)
               `(when var
                  (push (list ,(intern (symbol-name var) "KEYWORD") var)
                        ,list)))
ADD-IF-NOT-NULL

CL-USER 30 > (macroexpand-1 '(add-if-not-null width some-list))
(WHEN VAR (PUSH (LIST :WIDTH VAR) SOME-LIST))
T

【讨论】:

  • 这几乎是我需要的,但问题在于 (symbol-name 'width) 调用。宽度是一个函数参数,所以我需要用将变量名转换为字符串的东西来替换它。例如。我需要(some-function width)返回字符串“width”,另一个调用将是(some-function any-variable)返回“any-variable”。我怀疑我让这件事变得比它需要的更难,但在长时间的中断后我又回到了 lisp。
  • @Sprucial:查看我的编辑。抱歉,我想早点添加它,但分心了。不过,就在这里。也许这就是你需要的?
  • 感谢@Rainer Joswig。这几乎正​​是我所需要的。这是我最终得到的(defmacro add-if-not-null-macro (var lst) `(if ,var (append ,lst (list (intern (symbol-name (quote ,var)) "KEYWORD") ,var)) ,lst))
  • @Sprucial:请注意,您可以在 Common Lisp 中编写 list。无需写lst。另外:您要附加到列表的末尾。这是使用单链表的不好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多