当前位置:  开发笔记 > 编程语言 > 正文

如何在Common Lisp中从宏参数创建单个单词?

如何解决《如何在CommonLisp中从宏参数创建单个单词?》经验,为你挑选了2个好方法。

我有:

(defmacro test (a b c)
    `'(,a ,b ,c))

跑步(test apple banana cuba)给了(APPLE BANANA CUBA)预期.

如何让宏生成APPLEBANANACUBA?

我试过了:

(defmacro test (a b c)
        `'(,a,b,c))

(test ant bites chris)仍然运行仍然返回(ANT BITES CHRIS)三个单独的args列表.

我试过变化,似乎没有工作.像这个:

(defmacro test (a b c)
    `(apply #'concatenate 'symbol '(,a ,b ,c)))

显然,这会出错,因为'符号不是连接的有效输出类型.

我确信这是我对宏如何工作的一些基本误解,并且有一种简单的方法可以做到这一点.我错过了什么?



1> Barmar..:

将它们连接成一个字符串,然后从该字符串创建一个符号.

(defmacro test (a b c)
  (intern (concatenate 'string a b c)))

INTERN将在当前包中实习该字符串,您还可以使用它MAKE-SYMBOL来创建一个未处理的符号.



2> Rainer Joswi..:

关于宏及其实现的困惑

我确信这是我对宏如何工作的一些基本误解

是:

宏和创建"单词"是完全独立的,正交的概念.

Lisp中不存在'word'的概念.但有符号,字符串,数字,......

如果你想到APPLEBANANACUBA那么你可能意味着一个符号.

解决问题

    首先解决如何从符号列表中创建符号的问题

    实现宏

如果要创建符号串联的新符号,则需要:

    获取符号,将其名称作为字符串

    创建一个字符串,这是这些名称的串联

    从该字符串创建一个符号,可能在一个包中.

内爆操作

我们将此操作称为implode,这是它的历史名称:

(defun implode-symbols (symbols &optional (package *package*))
  (when symbols
    (values
     (intern (with-output-to-string (stream)
               (dolist (symbol symbols)
                 (write-string (symbol-name symbol) stream)))
             package))))


CL-USER 30 > (implode-symbols '(a - b - c - foo - bar))
A-B-C-FOO-BAR

现在,人们可以制作一个更通用的版本,它可以破坏所有东西:

(defun implode (things)
  (when things
    (values
     (intern (with-output-to-string (stream)
               (dolist (thing things)
                 (princ thing stream)))))))

CL-USER 31 > (implode '(a - b - c - foo :bar - 42 - "BAZ"))
A-B-C-FOOBAR-42-BAZ

一个宏在一些争论中爆发

鉴于我们是一个从事物列表中创建符号的函数,我们可以轻松编写宏:

CL-USER 37 > (defmacro test (a b c)
               `',(implode (list a b c)))
TEST

CL-USER 38 > (macroexpand-1 '(test foo bar baz))
(QUOTE FOOBARBAZ)
T

CL-USER 39 > (test foo bar baz)
FOOBARBAZ

原子,爆炸和爆炸

符号是原子.这意味着它们不是缺陷单元,它是链表的基本构建块.

你可以爆炸和内爆原子,这里是一个符号.

内爆符号FOOBAR- >FOOBAR

爆炸的符号FOOBAR- > F,O,O,B,A,R

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有