Skip to content
Development
Skill

/clojure-programmer

Clojure-specific philosophy, idioms, and judgment frameworks. Use when working with Clojure code. Emphasizes data-oriented design, runtime validation with spec, REPL-driven development, and the philosophy of simplicity over ease.

From plugin
opinionated-claude-skills
919 skills3 agents
Install
$ npx -y skills add Pyroxin/opinionated-claude-skills --skill clojure-programmer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/clojure-programmer

Context preview

The summary Claude sees to decide when to auto-load this skill.

Clojure-specific philosophy, idioms, and judgment frameworks. Use when working with Clojure code. Emphasizes data-oriented design, runtime validation with spec, REPL-driven development, and the philosophy of simplicity over ease.

SKILL.md

clojure-programmer.SKILL.md
name: clojure-programmer
description: Clojure-specific philosophy, idioms, and judgment frameworks. Use when working with Clojure code. Emphasizes data-oriented design, runtime validation with spec, REPL-driven development, and the philosophy of simplicity over ease.

Clojure Programmer Skill

**Target Clojure 1.12.3+** (current stable as of September 2025). Version history at https://github.com/clojure/clojure/blob/master/changes.md.

This skill provides judgment frameworks and philosophical grounding for expert-level Clojure development. It assumes you understand functional programming and Lisp basics from training, focusing instead on Clojure-specific philosophy, when/why guidance, and retrieval triggers for avoiding common mistakes.

<core_philosophy>

Core Philosophy: Simple Made Easy

**For foundational software engineering principles, see the software-engineer skill. For general FP principles, see the functional-programmer skill—this skill provides Clojure-specific guidance that supersedes those general patterns.**

**Rich Hickey's foundational distinction:** "Simple" means one thing, one concept, one task. "Easy" means familiar, near at hand. **Always choose simple over easy.**

This philosophy permeates every Clojure decision:

  • Maps over classes (simple: just data vs easy: familiar OOP)
  • Data orientation over objects (simple: transformations vs easy: encapsulation)
  • Immutability by default (simple: values don't change vs easy: mutation in place)
  • Runtime contracts over types (simple: validate what you need vs easy: compile-time guarantees)

**The critical insight:** Simplicity enables change. Easy rots into complexity. When facing a choice between "this feels familiar from Java/Python/JavaScript" and "this is the Clojure way," choose the Clojure way. The unfamiliarity is temporary; the simplicity compounds.

**"Programs must be written for people to read, and only incidentally for machines to execute."** — Hal Abelson, SICP

Code as Ontology: The Open-World Assumption

**From Rich Hickey's Spec-ulation:** Clojure's design was inspired by RDF's open-world assumption. **Code is an ontology of a solution.** Names create enduring semantic commitments.

Open Systems Enable Growth

**"If I put on a hat, it does not change what my family is."** — Rich Hickey

Maps are collections of keys, not the stuff inside the keys. Extra keys don't change identity:

;; These are the same entity with different knowledge
{:user/id 123 :user/name "Alice"}
{:user/id 123 :user/name "Alice" :user/email "alice@example.com"}

;; Identity preserved, knowledge accreted

**This is RDF's open-world assumption:**

  • You don't know everything about an entity upfront
  • New facts can always be added
  • Systems should tolerate unknown information
  • Prohibition ("no other keys allowed") turns growth into breakage

Spec Embodies Open-World Reasoning

**"Spec is about what you CAN do, not about what you CAN'T."** — Rich Hickey

Why spec doesn't allow closed maps:

;; If you could say "only these keys"
(s/def ::user (s/closed-keys :req [::id ::name]))

;; Then adding ::email later would BREAK everything
;; Every consumer would need updating
;; Growth becomes breakage
;; Cascading changes up the dependency tree

**The open-world discipline:**

  • Always presume you might receive more than you know about
  • Select the keys you need: `(select-keys user [::id ::name])`
  • Don't blindly display everything (might expose sensitive data)
  • Ignore what you don't understand
  • **Never prohibit growth**

Levels and Scopes: Don't Conflate

**Each level is a collection with two operations: add or remove.**

  • **Functions** — require args, provide return
  • **Namespaces** — collections of vars (adding vars = growth, removing = breakage)
  • **Artifacts** — collections of namespaces (adding namespaces = growth, removing = breakage)

**"My family doesn't change when I put on a hat."** A function changing (putting on a hat) doesn't change the namespace (the family). Don't version the namespace because a function changed. Don't version the artifact because a namespace changed.

Accretion Over Breakage

**Growth happens through accretion:**

  • Provide more (return additional keys)
  • Require less (make parameters optional)
  • Add new functions alongside old ones (foo and foo-2 coexist)

**Breakage happens through:**

  • Requiring more (mandatory parameters)
  • Providing less (removing return keys)
  • Removing functions
  • **Changing semantics under the same name**

**The discipline:** Turn breakage into accretion. Don't remove `foo`, add `foo-2`. Don't require new parameters, make them optional. Don't remove keys from returns, add new ones.

Knowledge Representation Connection

**For knowledge engineers:** This is why Clojure feels natural for ontology work. The language's data model mirrors RDF's assumptions:

  • **Open-world reasoning** — Unknown facts might exist
  • **Monotonic knowledge growth** — Add facts, don't retract (in public APIs)
  • **Identity vs. information** — Entity identity (qualified keywords) separate from information (map values)
  • **Schema evolution** — Adding predicates doesn't break existing queries
  • **Namespace = vocabulary** — Like RDF namespaces, prevents collisions

**Write Clojure code the way you'd design an ontology:** Open to extension, explicit about semantics, preserving meaning over time. </core_philosophy>

<repl_driven>

REPL-Driven Development: Living in Your Program

**The REPL isn't just a tool—it's how you think about Clojure development.** Stuart Halloway: "You're living in your program invoking your tools, instead of living in your tools invoking your program."

The Fundamental Shift

Traditional development: Write code → Compile → Run → Debug → Repeat REPL-driven development: Start program → Develop features while running → Test immediately → Never restart

**What this means practically:**

  • Launch your application once and keep it running
Read more
Ships withopinionated-claude-skills

This project descends from the personal prompts I'd been keeping for Claude Code prior to the release of skills and plugins. Over time it's also evolved into a sandbox where I figure out what makes Claude reliably good at a task, and find prompts that work.

Get the whole plugin

Other skills on opinionated-claude-skills.