gensym
gensym Function
Syntax:
gensym &optional x → new-symbol
Arguments and Values:
x—a string or a non-negative integer . Complicated defaulting behavior; see below. new-symbol—a fresh, uninterned symbol.
Description:
Creates and returns a fresh, uninterned symbol, as if by calling make-symbol. (The only difference between gensym and make-symbol is in how the new-symbol’s name is determined.)
The name of the new-symbol is the concatenation of a prefix, which defaults to "G", and a suffix, which is the decimal representation of a number that defaults to the value of *gensym-counter*.
If x is supplied, and is a string, then that string is used as a prefix instead of "G" for this call to gensym only.
If x is supplied, and is an integer , then that integer , instead of the value of *gensym-counter*, is used as the suffix for this call to gensym only.
If and only if no explicit suffix is supplied, *gensym-counter* is incremented after it is used.
Examples:
(setq sym1 (gensym)) → #:G3142
(symbol-package sym1) → NIL
(setq sym2 (gensym 100)) → #:G100
(setq sym3 (gensym 100)) → #:G100
(eq sym2 sym3) → false
(find-symbol "G100") → NIL, NIL
(gensym "T") → #:T3143
(gensym) → #:G3144
Side Effects:
Might increment *gensym-counter*.
Affected By:
*gensym-counter*Exceptional Situations:
Should signal an error of type type-error if x is not a string or a non-negative integer .
See Also:
gentemp, *gensym-counter*
Notes:
The ability to pass a numeric argument to gensym has been deprecated; explicitly binding *gensym-counter* is now stylistically preferred. (The somewhat baroque conventions for the optional argument are historical in nature, and supported primarily for compatibility with older dialects of Lisp. In modern code, it is recommended that the only kind of argument used be a string prefix. In general, though, to obtain more flexible control of the new-symbol’s name, consider using make-symbol instead.)
Expanded Reference: gensym
Basic usage
gensym creates a fresh, uninterned symbol with an automatically generated name. The default prefix is "G" followed by a counter value.
(gensym)
;; => #:G0 (exact number depends on *gensym-counter*)
(gensym)
;; => #:G1 (counter increments each call)
Custom prefix
You can supply a string to use as a prefix instead of "G".
(gensym "TEMP")
;; => #:TEMP2 (number depends on *gensym-counter*)
(gensym "MY-VAR")
;; => #:MY-VAR3
Each gensym is unique
Even with the same prefix, each call produces a distinct symbol.
(let ((a (gensym "X"))
(b (gensym "X")))
(eq a b))
=> NIL
Gensyms are uninterned
A gensym has no home package and cannot be found by find-symbol.
(let ((sym (gensym)))
(values (symbol-package sym)
(find-symbol (symbol-name sym))))
=> NIL
=> NIL
Using gensym in macros to avoid variable capture
The most common use of gensym is in macro definitions to create hygienic variable names.
(defmacro with-timing (&body body)
(let ((start (gensym "START"))
(result (gensym "RESULT")))
`(let ((,start (get-internal-real-time)))
(let ((,result (progn ,@body)))
(format t "Elapsed: ~D time units~%"
(- (get-internal-real-time) ,start))
,result))))
;; The macro expands using unique symbols to avoid name clashes
(macroexpand-1 '(with-timing (+ 1 2)))
;; => (LET ((#:START0 (GET-INTERNAL-REAL-TIME)))
;; (LET ((#:RESULT1 (PROGN (+ 1 2))))
;; (FORMAT T "Elapsed: ~D time units~%" (- (GET-INTERNAL-REAL-TIME) #:START0))
;; #:RESULT1))
Controlling the counter with gensym-counter
You can bind *gensym-counter* to control the suffix numbering.
(let ((*gensym-counter* 100))
(values (gensym) (gensym) (gensym)))
;; => #:G100
;; => #:G101
;; => #:G102