Here's my take:
(defun concatenate-symbol (package &rest arguments) "Returns a symbol whose name is a concatenation of printed representations of ARGUMENTS, printed as if by PRINC. If PACKAGE is NIL, the symbol is a fresh uninterned symbol. If PACKAGE is T, the symbol is interned in the current package. Otherwise the symbol is interned in the package designated by PACKAGE." (let ((name (with-output-to-string (s) (dolist (part arguments) (princ part s))))) (if package (intern name (if (eq t package) *package* package)) (make-symbol name))))
I'm a still bit non-plussed of when
(concatenate-symbol pkg "FOO-" (incf *my-counter* i) "-DING-" i "-" tail)
would be preferable to
(format-symbol pkg "FOO-~D-DING-~D-~A" (incf *my-counter* i) i tail)
...so I assume I am misunderstanding the typical use-cases.
well, the point in my original proposal was to cover most of the (my?) common usecases with a dwim function that is intuitive and easy to read:
(concatenate-symbol "FOO" some-symbol "BAR")
therefore adding the package argument makes it kinda pointless, we should just use format-symbol then. also another requirement that often comes up for me is to be able to control what should happen if the symbol already exists and it was not interned by us. i usually (setf (get symbol 'some-marker-that-it-was-created-by-us) t) and later check that when the interning is requested again.
all in all, the more i'm thinking about it, the less suitable i find it in alexandria. i guess people should just roll their own macros for specific use-cases or use format-symbol.