Concatenating symbols

Discussion of Common Lisp
Post Reply
lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Concatenating symbols

Post by lrodrig » Thu Jan 27, 2011 11:15 am

Hi,

I was wondering if there is a Common Lisp function that takes two (or more) input symbols to obtain an output symbol which is the concatenation of the inputs. I mean, something like:

(concatenate 'symbol 'a 'b) that would produce a new symbol ab (since "symbol" is not of type sequence, the concatenate function does not work in this case)

A possible solution would be to use (symbol-name ...) to transform the symbols into strings, concatenate them and then obtaining the final result by using (intern ...) but I think this can be quite inefficent. Is there a better way to do this?

Regards,
Luis.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Concatenating symbols

Post by ramarren » Thu Jan 27, 2011 12:57 pm

Symbols in Common Lisp are not, as you notice, sequences. They are fairly complex structures with multiple fields. One of those fields is a name, which is a string. SYMBOL-NAME doesn't "transform" a symbol into string, it retrieves its name. You have to create a new string to become a name for a symbol with a new name, and the procedure you describe is the simplest one. There is also SYMBOLICATE in Alexandria, which uses a somewhat optimized procedure for that, you can use that.

trillioneyes
Posts: 8
Joined: Sat Nov 20, 2010 10:00 pm

Re: Concatenating symbols

Post by trillioneyes » Thu Jan 27, 2011 8:54 pm

lrodrig wrote: A possible solution would be to use (symbol-name ...) to transform the symbols into strings, concatenate them and then obtaining the final result by using (intern ...) but I think this can be quite inefficent. Is there a better way to do this?
This would work (though I have no idea about efficiency), but it can give weird effects if you call it in two different packages:

Code: Select all

(defun concat-syms (&rest syms)
  (intern (apply #'concatenate 'string (mapcar #'symbol-name syms))))
(defpackage foo)
(concat-syms 'a 'b 'c)  ==> cl-user::abc
(in-package foo)
(concat-syms 'a 'b 'c) ==> foo::abc
Whether this makes a difference depends on your code; the biggest thing is that they do not compare equal under EQ. Probably the Alexandria thing circumvents this, but I haven't used it.

lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Re: Concatenating symbols

Post by lrodrig » Fri Jan 28, 2011 2:28 am

Thank you very much for your answers.

Luis.

Vivitron
Posts: 4
Joined: Mon Nov 22, 2010 2:05 pm

Re: Concatenating symbols

Post by Vivitron » Fri Jan 28, 2011 8:20 am

Paul Graham offers a slightly more flexible function in On Lisp (page 57). It will work on anything that can be sent to princ rather than just symbols:

Code: Select all

(defun mkstr (&rest args)
  "concatenates args by printing into string"
  (with-output-to-string (s)
    (dolist (a args) (princ a s))))


(defun symb (&rest args)
  "interns the mkstr output/returns as symbol"
  (values (intern (apply #'mkstr args))))
Docstrings added by me.

Post Reply