合并常见lisp中的符号

Posted

技术标签:

【中文标题】合并常见lisp中的符号【英文标题】:Merging symbols in common lisp 【发布时间】:2013-03-20 13:25:59 【问题描述】:

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

例子:

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

我想要什么,而不是:

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

【问题讨论】:

【参考方案1】:

你不能在 Lisp 中“合并符号”。

首先,5 不是一个符号,而是一个数字。如果您想要一个名为 "5" 的符号,则必须将其键入为 |5|(例如)。

如果函数采用符号A 和符号|5|,并产生符号A5,则它没有合并符号。它创建了一个新符号,其名称是这些输入符号名称的串联。

正确设计的 Lisp 程序很少依赖于符号的命名方式。它们依赖于作为唯一实体的符号。

如果您使用符号来标识事物,并且 5A 都标识了某个实体,那么最好的答案不一定是创建一个新符号,它至少在名称上是这两个符号。例如,更好的设计可能是接受名称是多方面的或以某种方式复合的。或许(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|

【讨论】:

【参考方案2】:

定义这个:

(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 函数(我忘记了 :() 将任何内容字符串化。

【讨论】:

函数string 将字符串指示符字符串化,而不是路径名【参考方案3】:

你问的问题的答案是

(defun concatenate-objects-to-symbol (&rest objects)
  (intern (apply #'concatenate 'string (mapcar #'princ-to-string objects))))
(concatenate-objects 'a 'b) ==> ab

哦,如果你想要一个 list 作为结果:

(defun xxxx (s1 s2) (list (concatenate-objects-to-symbol s1 s2)))

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

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

【讨论】:

只要你在你的 Lisp 监听器中输入一个标记,它被解释为一个符号名称,你就创建了一个符号。 不公平!你抄袭我的回答!! (定义 xxxx (s1 s2) ...)

以上是关于合并常见lisp中的符号的主要内容,如果未能解决你的问题,请参考以下文章

LISP 中的变量和符号有啥区别?

Common Lisp 中的原子和符号有啥区别?

解析 Common Lisp 列表中的符号

如何将字符串转换为符号以用作 Lisp“assoc”函数中的键?

循环宏中的常见 Lisp 绑定

MATLAB符号运算