Guides correct use of Elixir quote/unquote, __using__, module attributes, @before_compile, and compile-time validation when building macros or declarative DSLs like Ecto.Schema, Absinthe, Plug.Router, or ExUnit. For writing or reviewing macro/DSL code once a function won't suffice.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pproenca-dot-skills-1:elixir-meta-programmingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
How to build Elixir macros and declarative DSLs *correctly* — for the case where a macro is genuinely warranted and a plain function won't do. Each rule corrects a specific wrong default a capable model makes once it starts writing `quote`/`unquote`, `__using__`, and `@before_compile`; nothing here restates macro basics the model already knows.
How to build Elixir macros and declarative DSLs correctly — for the case where a macro is genuinely warranted and a plain function won't do. Each rule corrects a specific wrong default a capable model makes once it starts writing quote/unquote, __using__, and @before_compile; nothing here restates macro basics the model already knows.
The default answer is no — reach for a higher-order function, a behaviour, or data-plus-an-interpreter first. That gate is not this skill's job; it lives in the sibling skills and you should apply it before opening this one:
staff-level-elixir → data-functions-over-macros (solve it with a function first)adversarial-elixir → meta-functions-not-macro-dsl, meta-use-is-not-import, meta-no-compile-time-couplingA macro earns its place only when you need something a function cannot give — new syntax, control over whether/when arguments evaluate, or code that must exist at compile time (compiling a schema, generating clauses from a declaration list). Once you've crossed that threshold, this skill is how you do it right.
quote block versus a runtime function, and how arguments evaluateschema/spec/route/workflow block that collects declarations and generates a moduleuse MyDSL — what __using__ should inject and what belongs in @before_compilemix compile with an error that points at the user's source| # | Category | Prefix | Covers |
|---|---|---|---|
| 1 | Macro Design | macro | The shape of a single macro — thin macro over a runtime function; defguard for guard-safe constructs |
| 2 | Quote & Hygiene | quote | Compile-time semantics traps — multiple evaluation, Macro.escape, hygiene vs var! |
| 3 | DSL Construction | dsl | Assembling a block DSL — accumulating attributes + @before_compile, minimal __using__, unquote fragments, introspection |
| 4 | Compile-Time Validation | valid | Failing well — validate while compiling, locate errors at the caller's line |
macro-thin-delegate-runtime — quote to a single call into a plain function; keep logic testable and out of every call sitemacro-defguard-for-guards — defguard when the construct must work inside a guardquote-bind-quoted-single-eval — bind_quoted so a repeated unquote argument evaluates oncequote-escape-runtime-data — Macro.escape/1 before splicing a computed term into quotequote-rely-on-hygiene — rely on hygiene; use var! only when injecting a name is the documented contractdsl-accumulate-attributes — record declarations in an accumulate: true attribute, generate in @before_compiledsl-using-minimal — __using__ does setup only; generation belongs in @before_compiledsl-unquote-fragments — def unquote(name)(...) in a comprehension to emit one clause per declarationdsl-introspection-function — generate a __schema__-style reflection function so callers read datavalid-fail-at-compile-time — validate in the macro body, not the returned quote, so errors fire at mix compilevalid-locate-errors-at-caller — raise from the declaration macro / capture __CALLER__ so errors cite the user's lineRead a reference file when its decision comes up. Each rule names the wrong default it corrects, then shows the canonical way (with an Incorrect/Correct contrast only where the wrong way is a real trap).
staff-level-elixir — the broader Elixir/OTP/Ecto/Phoenix judgment skill; owns the "prefer a function over a macro" gateadversarial-elixir — architecture-level review that flattens unnecessary macro DSLs; the diagnostic counterpart to this skill| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and source references |
npx claudepluginhub joshuarweaver/cascade-code-general-misc-1 --plugin pproenca-dot-skills-1Implements Crystal macros for compile-time metaprogramming, code generation, DSLs, AST manipulation, and type-safe abstractions.
Provides Elixir best practices and OOP-to-functional shifts: avoid unnecessary processes, use pattern matching/with for control flow, {:ok/:error} handling, behaviors/protocols for polymorphism.
Reviews and refactors existing Elixir/OTP/Ecto/Phoenix code that carries alien mental models (OO ceremony, imperative loops, nil-checking) into idiomatic BEAM patterns. Deletes entire layers like repository wrappers, service objects, and per-entity GenServers.