# macro/syntax-quote Like `macro/quote`, but with two differences aimed at hygienic macro code generation: 1. `$param` references are substituted (acts like the normal macro body) — no need for `[macro/unquote ...]` around parameters. 2. Bare symbols (e.g. `tmp`) are automatically renamed to unique gensym'd names (`tmp#N`), so they cannot collide with variables at the call site. ## Syntax
[macro/syntax-quote expr]
## Why hygiene matters Deft macros are not hygienic by default. A macro that introduces a symbol like `tmp` can clobber a same-named variable in the caller's scope:
defmacro swap {|a b|
    [macro/quote {
        set tmp $a          # ← 'tmp' collides with caller's 'tmp'!
        set $a $b
        set $b $tmp
    }]
}

set tmp "outer"
[swap x y]
echo $tmp                  # ← clobbered by the macro's tmp
`macro/syntax-quote` fixes this by renaming `tmp` to a unique name (`tmp#42`, `tmp#43`, …) every expansion:
defmacro swap {|a b|
    [macro/syntax-quote {
        set tmp $a          # ← auto-gensym'd to tmp#N
        set $a $b
        set $b $tmp
    }]
}

set tmp "outer"
[swap x y]
echo $tmp                  # ← still "outer" — safe
## Substitution rules | Inside `macro/syntax-quote` | Behaviour | |----------------------|-----------| | `tmp` (bare symbol) | Renamed to `tmp#N` | | `$param` | Substituted with the macro argument | | `:keyword` | Preserved literally | | `set` / `if` / `for` / `while` / `begin` | Preserved (special forms, not gensym'd) | | `__lambda` and other `__`-prefixed | Preserved (internal forms) | | `[macro/unquote $expr]` | Substituted (rarely needed — `$param` already is) | | `[macro/splice $list]` | Inlined into the parent form | ## Example: rest-collector + splice
defmacro build-code {|@exprs|
    [macro/syntax-quote {
        [begin [macro/splice $exprs]]
    }]
}

set a 1
set b 2
[build-code [set a 10] [set b 20]]
# expands to: [begin [set a 10] [set b 20]]
## Escape with macro/unquote `[macro/unquote $expr]` inside `macro/syntax-quote` is mostly redundant (since `$param` is already substituted). It's occasionally useful for forcing substitution of a non-`$param` expression:
defmacro with-logging {|body|
    [macro/syntax-quote {
        set log @{}
        [macro/unquote $body]
    }]
}
Here `log` is gensym'd (hygiene), and the body block is inlined via unquote. ## Important: use `[...]`, not `(...)` Deft's bare `( ... )` parens are infix-only. `[macro/unquote $x]` is correct; `(macro/unquote $x)` is a syntax error. ## See Also `macro/quote`, `macro/unquote`, `macro/gensym`, `macro/splice`, `begin`, `defmacro`