faster WHICHEVER
[alexandria.git] / symbols.lisp
blob0347548d92a4f913ce688463eb94b154ae43d397
1 (in-package :alexandria)
3 (declaim (inline ensure-symbol))
4 (defun ensure-symbol (name &optional (package *package*))
5 "Returns a symbol with name designated by NAME, accessible in package
6 designated by PACKAGE. If symbol is not already accessible in PACKAGE, it is
7 interned there. Returns a secondary value reflecting the status of the symbol
8 in the package, which matches the secondary return value of INTERN.
10 Example: (ENSURE-SYMBOL :CONS :CL) => CL:CONS, :EXTERNAL"
11 (intern (string name) package))
13 (defun maybe-intern (name package)
14 (values
15 (if package
16 (intern name (if (eq t package) *package* package))
17 (make-symbol name))))
19 (declaim (inline format-symbol))
20 (defun format-symbol (package control &rest arguments)
21 "Constructs a string by applying ARGUMENTS to CONTROL as if by FORMAT, and
22 then creates a symbol named by that string. If PACKAGE is NIL, returns an
23 uninterned symbol, if package is T, returns a symbol interned in the current
24 package, and otherwise returns a symbol interned in the package designated by
25 PACKAGE."
26 (maybe-intern (apply #'format nil control arguments) package))
28 (defun make-keyword (name)
29 "Interns the string designated by NAME in the KEYWORD package."
30 (intern (string name) :keyword))
32 (defun make-gensym (name)
33 "If NAME is a non-negative integer, calls GENSYM using it. Otherwise NAME
34 must be a string designator, in which case calls GENSYM using the designated
35 string as the argument."
36 (gensym (if (typep name '(integer 0))
37 name
38 (string name))))
40 (defun make-gensym-list (length &optional (x "G"))
41 "Returns a list of LENGTH gensyms, each generated as if with a call to MAKE-GENSYM,
42 using the second (optional, defaulting to \"G\") argument."
43 (let ((g (if (typep x '(integer 0)) x (string x))))
44 (loop repeat length
45 collect (gensym g))))
47 (defun symbolicate (&rest things)
48 "Concatenate together the names of some strings and symbols,
49 producing a symbol in the current package."
50 (let* ((length (reduce #'+ things
51 :key (lambda (x) (length (string x)))))
52 (name (make-array length :element-type 'character)))
53 (let ((index 0))
54 (dolist (thing things (values (intern name)))
55 (let* ((x (string thing))
56 (len (length x)))
57 (replace name x :start1 index)
58 (incf index len))))))