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.
Concatenating symbols
Re: Concatenating symbols
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.
-
- Posts: 8
- Joined: Sat Nov 20, 2010 10:00 pm
Re: Concatenating symbols
This would work (though I have no idea about efficiency), but it can give weird effects if you call it in two different packages: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?
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
Re: Concatenating symbols
Thank you very much for your answers.
Luis.
Luis.
Re: Concatenating symbols
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:
Docstrings added by me.
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))))