# macro/compile-when
Compile-time conditional: evaluate `cond` during compilation and emit
`body` only if truthy. If falsy, `body` is skipped entirely — it
produces zero runtime code (a single `push_null`), not even a
branch.
[macro/compile-when cond body]
## How it works
`cond` is compiled and executed through the VM at compile time (the
same mechanism `require` uses to run module-level forms). The result is
checked for truthiness:
- truthy → `body` is compiled in place, as if the
`macro/compile-when` wrapper weren't there.
- falsy → `body` is discarded; the call site emits `push_null`.
This is the foundation of zero-cost configurable logging: the level
check happens during compilation, so filtered-out calls never enter the
bytecode.
## Example — level-filtered logging
def log-level ([os/env "DEFT_LOG_LEVEL"] or "debug") defmacro debug {|@args| [macro/compile-when [in? @{"debug"} $log-level] [log/debug [macro/splice $args]]] }
When this module is `require`d (which runs `def log-level ...` at
compile time), each `[debug "msg"]` call site checks the level during
compilation. If `DEFT_LOG_LEVEL=error`, the entire `log/debug` call is
elided — the bytecode for that call site is a single `push_null`.
## Conditions must be evaluable at compile time
`cond` runs through the VM during compilation, so it can reference:
- literals (`true`, `false`, `nil`, numbers, strings, keywords)
- globals defined before the `macro/compile-when` form (including those
defined by `require`d modules, since `require` runs `def` forms at
compile time)
- pure functions of the above (`in?`, predicates, infix operators
inside `(...)`, …)
It cannot reference variables that only exist at runtime
(locals inside a function body, closure captures, etc.) — those
aren't available when the compiler evaluates the condition.
## Notes
- If the condition fails to compile or the VM isn't available,
`macro/compile-when` conservatively emits `body` (fail-open).
- `macro/compile-when` is a special form handled by the compiler, not a
macro — it can't be redefined or shadowed.
- The condition is evaluated once per call site, at compile time. The
level can't change at runtime; changing `DEFT_LOG_LEVEL` requires a
recompile.
## See Also
`defmacro`, `require`, `if`