ˆᵛˆ*_*ˆᵛˆ 0 macros common-lisp
我有:
(defmacro test (a b c)
`'(,a ,b ,c))
Run Code Online (Sandbox Code Playgroud)
跑步(test apple banana cuba)给了(APPLE BANANA CUBA)预期.
如何让宏生成APPLEBANANACUBA?
我试过了:
(defmacro test (a b c)
`'(,a,b,c))
Run Code Online (Sandbox Code Playgroud)
但(test ant bites chris)仍然运行仍然返回(ANT BITES CHRIS)三个单独的args列表.
我试过变化,似乎没有工作.像这个:
(defmacro test (a b c)
`(apply #'concatenate 'symbol '(,a ,b ,c)))
Run Code Online (Sandbox Code Playgroud)
显然,这会出错,因为'符号不是连接的有效输出类型.
我确信这是我对宏如何工作的一些基本误解,并且有一种简单的方法可以做到这一点.我错过了什么?
将它们连接成一个字符串,然后从该字符串创建一个符号.
(defmacro test (a b c)
(intern (concatenate 'string a b c)))
Run Code Online (Sandbox Code Playgroud)
INTERN将在当前包中实习该字符串,您还可以使用它MAKE-SYMBOL来创建一个未处理的符号.
关于宏及其实现的困惑
我确信这是我对宏如何工作的一些基本误解
是:
宏和创建"单词"是完全独立的,正交的概念.
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
Run Code Online (Sandbox Code Playgroud)
现在,人们可以制作一个更通用的版本,它可以破坏所有东西:
(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
Run Code Online (Sandbox Code Playgroud)
一个宏在一些争论中爆发
鉴于我们是一个从事物列表中创建符号的函数,我们可以轻松编写宏:
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
Run Code Online (Sandbox Code Playgroud)
原子,爆炸和爆炸
符号是原子.这意味着它们不是缺陷单元,它是链表的基本构建块.
你可以爆炸和内爆原子,这里是一个符号.
FOO和BAR- >FOOBARFOOBAR- > F,O,O,B,A,R| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |