Skip to content
Agentmart
Submit a tool

functions

Clean-code functions — small, do one thing, one abstraction level, few arguments, no side effects, command-query separation, plus DRY and refactor discipline.

Skill by hzblj

IndexedMIT★ 1
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/hzblj-functions

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Clean-code functions — small, do one thing, one abstraction level, few arguments, no side effects, command-query separation, plus DRY and refactor discipline. Use when writing or reviewing functions. Triggers on: function too long, do one thing, too many arguments, side effects, command query, DRY, extract function, refactor.

Use cases: writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/functions

What's inside

Skill name
functions
Description
Clean-code functions — small, do one thing, one abstraction level, few arguments, no side effects, command-query separation, plus DRY and refactor discipline. Use when writing or reviewing functions. Triggers on: function too long, do one thing, too many arguments, side effects, command query, DRY, extract function, refactor.
License
MIT
Instructions
421 lines in SKILL.md · view on GitHub

Files (2)

  • SKILL.md
  • openai.yaml · agents/

SKILL.md (first lines)

# Functions

Functions are the verbs of your system. The best ones are small, do exactly one thing, and read top-to-bottom like a story where each line hands off to the next. This file covers size, single responsibility, abstraction levels, arguments, side effects, and command-query separation.

Good functions lean hard on good names — see [meaningful-names](../meaningful-names/SKILL.md) first. For how functions should signal failure, see [error-handling](../error-handling/SKILL.md).

## Quick Reference

| Principle | Smell | Fix |
| --- | --- | --- |
| Small functions | 80-line function | Extract named helpers |
| Do one thing | Comment-labeled sections | One function per section |
| One abstraction level | Policy mixed with byte-twiddling | Push detail down a level |
| Guard clauses / early returns | Deeply nested happy path | Return early on edge cases; keep happy path flat |
| No clever code | Nested ternary / dense one-liner | Plain, predictable code; name the intermediates |
| Bury the switch | `switch` in a caller | Lookup map / factory / polymorphism |
| Low argument count | 4+ params | Group into an object |
| Monadic forms | Flag arguments | Question, transform, or event only |
| Group related args | `x, y` passed everywhere | `Point`, `SpellCast` object |
| No hidden side effects | `check*` that also mutates | Make the effect explicit |
| Command-Query Separation | Function returns AND mutates | Split into a command and a query |

## Small Functions — Extract Relentlessly

A large function buries the business logic under low-level detail. The single most effective refactoring you can perform is to pull each coherent chunk into a well-named helper. The names of the extracted functions become the documentation, and the parent function becomes a table of contents.

```ts
// Bad — one function doing enrollment, sorting, and welcome all at once
const enrollStudent = (student: Student, hat: SortingHat) => {
  if (!student.name || student.age < 11) {
    throw new Error('Invalid student')
  }

  let house: House
  const traits = student.traits
  if (traits.includes('brave')) house = houses.gryffindor
  else if (traits.includes('cunning')) house = houses.slytherin
  else if (traits.includes('wise')) house = houses.ravenclaw
  else house = houses.hufflepuff

  house.members.push(student)
  student.house = house

  owlPost.send(student, `Welcome to ${house.name}!`)
  house.points += 5
}
```

```ts
// Good — each step is a named helper; the parent reads like a summary
const enrollStudent = (student: Student, hat: SortingHat) => {
  assertEligible(student)
  const house = hat.sortIntoHouse(student)
  addToHouse(student, house)
  sendWelcomeOwl(student, house)
}
```

Now `enrollStudent` documents itself, and each helper (`assertEligible`, `sortIntoHouse`, `addToHouse`, `sendWelcomeOwl`) can be read, tested, and reused on its own.

## Do One Thing — Tell a Story

A function should do one thing, do it well, and do it only. The clearest test: if you find yourself writing comments that label *sections* — `// initialization`, `// validation`, `// main logic` — each of those sections is a separate thing, and each wants to be its own function. A function that does one thing leads the reader naturally to the next step.

```ts
// Bad — the section comments are a confession that this does three things
const processHousePoints = (house: House) => {
  // validate
  if (house.points < 0) house.points = 0

  // calculate bonus
  const bonus = house.wins * 10 + house.detentions * -5

  // persist and notify
  house.points += bonus
  db.save(house)
  greatHall.updateHourglass(house)
}
```

```ts
// Good — one thing per function; the story reads in order
const processHousePoints = (house: House) => {
  normalizePoints(house)
  applyBonus(house, calculateBonus(house))
  recordAndDisplay(house)
}
```

If every function does one thing, you can describe it in a single sentence with no "and". `processHousePoints` no longer needs comments — the helper names tell the story.

## One Level of Abstraction Per Function

Within a single function, don't mix high-level policy ("award the house cup") with low-level mechanics (string concatenation, array index math). Jumping abstraction levels forces the reader to constantly change altitude and obscures what the function is really about.

```ts
// Bad — high-level "announce winner" sits next to low-level string building
const announceHouseCupWinner = (houses: House[]) => {
  const winner = houses.sort((a, b) => b.points - a.points)[0]

  let banner = ''
  for (let i = 0; i < winner.name.length; i++) {
    banner += winner.name[i].toUpperCase()
  }
  banner = '🏆 ' + banner + ' 🏆'

  greatHall.display(banner)
}
```

```ts
// Good — every line in the parent is the same altitude
const announceHouseCupWinner = (houses: House[]) => {
  const winner = findLeadingHouse(houses)
  const banner = formatWinnerBanner(winner)
  greatHall.display(banner)
}

const formatWinnerBanner = (house: House): string => {

From hzblj/skills, MIT.

More from hzblj/skills

Signals

Stars
1
Forks
0
Open issues
0
Last commit (this folder)
Jul 15, 2026 (3 months ago)
Last release
Aug 19, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from hzblj

Cite this page

functions skill. Agent Mart. https://agentmart.dev/skills/hzblj-functions (last updated 2026-10-24)