Agent Skills: Fennel Language

Expert guidance for Fennel code in all forms. Load this skill whenever a task involves reading, writing, debugging, reviewing, translating, or reasoning about Fennel.

UncategorizedID: datwaft/dotfiles/fennel-lang

Install this agent skill to your local

pnpm dlx add-skill https://github.com/datwaft/dotfiles/tree/HEAD/.config/opencode/skills/fennel-lang

Skill Files

Browse the full folder contents for fennel-lang.

Download Skill

Loading file tree…

.config/opencode/skills/fennel-lang/SKILL.md

Skill Metadata

Name
fennel-lang
Description
Expert guidance for Fennel code in all forms. Load this skill whenever a task involves reading, writing, debugging, reviewing, translating, or reasoning about Fennel.

Fennel Language

Fennel is a Lisp that compiles to Lua. It preserves Lua runtime semantics while providing Lisp syntax, expression-oriented forms, pattern matching, and macros.

This skill is language-first: prioritize semantics, forms, idioms, and reasoning. Do not assume tooling or project setup unless explicitly requested.

Use this skill when

  • writing, editing, reviewing, or refactoring Fennel code
  • translating between Lua and Fennel
  • explaining Fennel syntax, forms, macros, or runtime behavior
  • debugging compile-time and runtime issues
  • evaluating idiomatic quality and semantic correctness

Non-negotiable Fennel model

  • Fennel is fully interoperable with Lua; compiled output should not add runtime overhead.
  • Everything is expression-oriented.
  • Tables are the core runtime data structure and are mutable.
  • :name syntax is a string literal, not a keyword type.
  • nil means absence; setting a table key to nil removes that key.
  • Prefer let and local for immutable locals; use var only for intentional reassignment.
  • fn has no arity checks; lambda enforces required arguments.
  • Operators (+, =, and, etc.) and .. are special forms, not higher-order functions.
  • Operator argument counts are fixed at compile-time.
  • Pattern matching is ordered: first matching clause wins.
  • In case, ?x means maybe-nil binding and _x means ignored binding.
  • Sequential patterns are prefix matches; [] matches any table.
  • match auto-pins existing bindings; case binds fresh names unless explicitly pinned.
  • Native multiple return values are common and affect composition behavior.
  • Iterators are foundational (each, for, icollect, collect, accumulate) rather than seq abstractions.
  • Macros are compile-time transformations running in compiler scope, not runtime scope.
  • Macro hygiene matters: use gensym (name#) for helper locals.
  • Modules are plain returned values (usually tables) with explicit exports.

Coding defaults

  • Keep code idiomatic to both Fennel readers and Lua runtime constraints.
  • Favor simple, explicit forms over clever macro-heavy abstractions.
  • Use if for value branches and when for side effects.
  • Keep var lifetimes tight.
  • Prefer destructuring where it improves readability.
  • Prefer static field/method syntax (foo.bar, foo:bar) when possible.
  • Handle expected failures with (values nil err) and case/case-try patterns.
  • Reserve error/assert for unrecoverable paths or boundary failures.
  • Treat lua escape hatch as temporary or constrained interop aid.
  • Avoid deprecated or legacy compatibility forms in new code.

Macro defaults

  • Write a macro only when syntax transformation is required.
  • Design macro expansion first, then macro call shape.
  • Prefer quasiquote/unquote templates over manual list/sym construction.
  • Reject malformed macro inputs with assert-compile and source-aware forms.
  • Avoid caller-scope assumptions; require runtime dependencies inside expansion when needed.

Clojure-to-Fennel guardrails

  • Do not assume clojure.core runtime facilities.
  • Do not assume dynamic var/binding semantics.
  • Do not assume persistent collection semantics or seq-first APIs.
  • Translate to iterator-native and table-native patterns.
  • Keep module export and visibility model explicit and Lua-friendly.

Reference map

Working approach

  • Preserve project conventions when they differ from defaults.
  • Avoid broad refactors unless requested.
  • Prefer exact semantics over surface-level translation.
  • If uncertain about a form or edge case, verify against references/reference.md before emitting code.