# macro/gensym Generate a unique keyword value of the form `:prefix#N`. Each call returns a distinct value; the counter is monotonic per process.
[macro/gensym "tmp"]   # :tmp#0
[macro/gensym "tmp"]   # :tmp#1
[macro/gensym "log"]   # :log#2
## Syntax
[macro/gensym prefix]
`prefix` is a string; the result is `:<prefix>#<counter>`. ## When to use it `macro/gensym` is for producing unique runtime values — opaque tokens, unique map keys, sentinel values:
def session-id [macro/gensym "session"]    # :session#5 — guaranteed unique
[assoc $cache $session-id $payload]
## Runtime vs compile-time — the gotcha Deft macros expand at compile time via syntactic substitution; the macro body is inlined, not executed, during expansion. `[macro/gensym ...]` runs at runtime, so a value it returns cannot become the literal name of a new variable — deft `set` takes a literal identifier, not a value:
defmacro with-temp {|body|
    set tok [macro/gensym "tok"]
    [macro/quote {
        set $tok "temp"      # ✗ won't work — $tok is a value, not a name
        [macro/unquote $body]
    }]
}
For compile-time symbol hygiene inside generated code, use `macro/syntax-quote` instead — it auto-gensyms bare symbols *during expansion*, producing fresh identifier names that the compiler then treats as real variables:
defmacro swap {|a b|
    [macro/syntax-quote {
        set tmp $a           # ← 'tmp' renamed to tmp#N at compile time
        set $a $b
        set $b $tmp
    }]
}
## Notes - The prefix is a string literal. - The counter is process-global (shared across all runtimes in the process); uniqueness is guaranteed within a single process, not across them. - The result is a keyword — comparable with `==`, usable as a map key. ## See Also `macro/syntax-quote`, `macro/quote`, `macro/unquote`, `defmacro`