Merging symbols in common lisp
Asked Answered
L

4

4

I want to insert a char into a list. However, I want to merge this char with the last symbol in the list. With appends and cons the result is always two different symbols. Well, I want one merged symbol to be my result.

Example:

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

What I would like to have, instead of:

       (XXXX 'a '5) ====> (a 5)   
Lustrous answered 29/3, 2013 at 19:25 Comment(0)
S
12

You cannot "merge symbols" in Lisp.

First of all, 5 is not a symbol, but a number. If you want a symbol named "5" you have to type it as |5| (for example).

If a function takes the symbol A and symbol |5|, and produces the symbol A5, it has not merged symbols. It has created a new symbol whose name is the catenation of the names of those input symbols.

Properly designed Lisp programs rarely depend on how a symbol is named. They depend on symbols being unique entities.

If you're using symbols to identify things, and both 5 and A identify some entity, the best answer isn't necessarily to create a new symbol which is, in name at least, is a mashup of these two symbols. For instance, a better design might be to accept that names are multi-faceted or compound in some way. Perhaps the list (A 5) can serve as a name.

Common Lisp functions themselves can have compound names. For instance (setf foo) is a function name. Aggregates like lists can be names.

If you simply need the machine to invent unique symbols at run-time, consider using the gensym function. You can pass your own prefix to it:

(gensym "FOO") -> #:FOO0042

Of course, the prefix can be the name of some existing symbol, pulled out via symbol-name. The symbol #:FOO0042 is not unique because of the 0042 but because it is a freshly allocated object in the address space. The #: means it is not interned in any package. The name of the symbol is FOO0042.

If you still really want to, a simple way to take the printed representation of a bunch of input objects and turn it into a symbol is this:

(defun mashup-symbol (&rest objects)
  (intern (format nil "~{~a~}" objects)))

Examples:

(mashup-symbol 1 2 3) -> |123|

(mashup-symbol '(a b) 'c 3) -> |(A B)C3|
Supercharger answered 29/3, 2013 at 20:25 Comment(0)
P
5

Define this:

(defun symbol-append (&rest symbols) 
  (intern (apply #'concatenate 'string 
                 (mapcar #'symbol-name symbols))))

and then use it as:

* (symbol-append 'a 'b 'c)
ABC

* (apply #'symbol-append '(a b c))
ABC

If you expect your arguments to contain stuff besides symbols, then replace symbol-name with:

   (lambda (x)
     (typecase x ...)) 

or a pre-existing CL function (that I've forgotten :() that stringifies anything.

Pushing answered 29/3, 2013 at 20:10 Comment(1)
Function string stringifies what string designators, but not, say, pathnamesTwotone
T
2

The answer to the question you ask is

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

Oh, if you want a list as the result:

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

However, I am pretty sure this is not the question you actually want to ask.

Creating new symbols programmatically is not something beginners should be doing...

Twotone answered 29/3, 2013 at 19:31 Comment(2)
As soon as you enter a token into your Lisp listener, which is interpreted as a symbol name, you've created a symbol.Supercharger
No fair! You copied my answer!! (define xxxx (s1 s2) ...) <smiley>Pushing
W
1

There is also a utility function in the package ALEXANDRIA called SYMBOLICATE which concatenates any symbol, string or character to a symbol in the current package.

(symbolicate :a 'bc #\D "123" #\4)  -> ABCD1234

Documentation

Though numbers are not accepted and must be converted to strings beforehand. The other answers show various ways of how this can be done.

Whooper answered 22/6 at 17:43 Comment(2)
But OP seeks to combine, e.g., 5 and a to form a symbol, which symbolicate can't do. To be fair, OP should have provided more detail.Pyrotechnics
I see what you mean but i think what OP seeks is not exactly obvious as the question contains various contradictions. I'll edit my answer and make it a bit more general.Whooper

© 2022 - 2024 — McMap. All rights reserved.