我想在列表中插入一个字符。但是,我想将此char与列表中的最后一个符号合并。有了追加和缺点,结果总是两个不同的符号。好吧,我想要一个合并的符号作为我的结果。
示例:
(XXXX 'a '5) ====> (a5)
我想要的是,而不是:
(XXXX 'a '5) ====> (a 5)
答案 0 :(得分:10)
你不能在Lisp中“合并符号”。
首先,5
不是符号,而是数字。如果您需要名为"5"
的符号,则必须将其键入|5|
(例如)。
如果函数采用符号A
和符号|5|
,并生成符号A5
,则它没有合并符号。它创建了一个新符号,其名称是这些输入符号名称的连接。
正确设计的Lisp程序很少依赖于符号的命名方式。它们依赖于符号是唯一的实体。
如果您使用符号来识别事物,并且5
和A
都标识某个实体,那么最佳答案不一定是创建一个新符号,至少在名称上,是这两个符号的混搭。例如,更好的设计可能是接受名称是多方面的或以某种方式复合。也许列表(A 5)
可以作为名称。
Common Lisp函数本身可以有复合名称。例如,(setf foo)
是函数名称。像列表这样的聚合可以是名称。
如果您只是需要机器在运行时创建唯一符号,请考虑使用gensym
函数。您可以将自己的前缀传递给它:
(gensym "FOO") -> #:FOO0042
当然,前缀可以是某些现有符号的名称,通过symbol-name
拉出。由于#:FOO0042
,符号0042
不是唯一的,因为它是地址空间中新分配的对象。 #:
表示它不在任何包中实习。符号的名称为FOO0042
。
如果你真的想要,一个简单的方法来获取一堆输入对象的打印表示并将其转换为符号是这样的:
(defun mashup-symbol (&rest objects)
(intern (format nil "~{~a~}" objects)))
示例:
(mashup-symbol 1 2 3) -> |123|
(mashup-symbol '(a b) 'c 3) -> |(A B)C3|
答案 1 :(得分:3)
定义:
(defun symbol-append (&rest symbols)
(intern (apply #'concatenate 'string
(mapcar #'symbol-name symbols))))
然后将其用作:
* (symbol-append 'a 'b 'c)
ABC
* (apply #'symbol-append '(a b c))
ABC
如果您希望您的参数包含除符号之外的内容,请将symbol-name
替换为:
(lambda (x)
(typecase x ...))
或预先存在的CL函数(我忘记了:()将任何字符串化。
答案 2 :(得分:2)
你问的问题的答案是
(defun concatenate-objects-to-symbol (&rest objects)
(intern (apply #'concatenate 'string (mapcar #'princ-to-string objects))))
(concatenate-objects 'a 'b) ==> ab
哦,如果你想要一个列表:
(defun xxxx (s1 s2) (list (concatenate-objects-to-symbol s1 s2)))
但是,我很确定这不你实际上想要提出的问题。
以编程方式创建新符号不是初学者应该做的事情......