在 Common Lisp 中合并符号

问题描述 投票:0回答:4

我想将一个字符插入到列表中。 但是,我想将此字符与列表中的最后一个符号合并。 对于appends和cons,结果总是两个不同的符号。 好吧,我想要一个合并符号作为我的结果。

示例:

       (XXXX 'a '5) ====>  (a5)    

我想要什么,而不是:

       (XXXX 'a '5) ====> (a 5)   
merge lisp common-lisp symbols
4个回答
11
投票

你不能在 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|

5
投票

定义这个:

(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
投票

您所问问题的答案是

(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)))

但是,我很确定这不是您真正想要问的问题。

以编程方式创建新符号不是初学者应该做的事情......


0
投票

ALEXANDRIA
中还有一个名为
SYMBOLICATE
的实用函数,它将字符串和/或符号连接到符号。

(symbolicate 'abc "123")  -> ABC123

文档

© www.soinside.com 2019 - 2024. All rights reserved.