js-ts-fp

Functional Programming Engineering Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "js-ts-fp" with this command: npx skills add adibfirman/dotfiles/adibfirman-dotfiles-js-ts-fp

Functional Programming Engineering Skill

Write and review code using functional programming principles like a top engineer.

Workflow

Step 1: Analyze the Codebase

Before writing or reviewing any code, examine the repository:

  • Confirm TypeScript or JavaScript: Check for .ts , .tsx , .js , .jsx files and package.json

  • Find existing patterns: Look at 2-3 representative files to understand current conventions

  • Check tsconfig.json: Note strict mode, module system, and target ES version

Step 2: Apply FP Principles

Apply these principles (all natively supported in TS/JS):

Principle Description

Pure functions No side effects, same input → same output

Immutability Never mutate, always return new values

Declarative style Describe what, not how

Function composition Build complex from simple functions

Higher-order functions Functions that take/return functions

Avoid shared state No globals, no mutation of external state

Discriminated unions TypeScript pattern matching alternative

Step 3: Execute Task

Writing new code:

  • Follow existing repo conventions for file structure and naming

  • Use FP patterns consistent with what's already in the codebase

  • If no FP patterns exist, introduce them gradually and idiomatically

Reviewing code:

  • Identify imperative patterns that could be functional

  • Flag mutation, side effects, shared state

  • Suggest specific refactors with before/after examples

Refactoring:

  • Preserve behavior while improving structure

  • Transform loops → map/filter/reduce

  • Extract pure functions from impure ones

  • Isolate side effects to boundaries

Core FP Transformations

Imperative → Declarative

// Before: imperative loop let results = []; for (let i = 0; i < items.length; i++) { if (items[i].active) { results.push(transform(items[i])); } }

// After: declarative const results = items .filter(item => item.active) .map(transform);

Mutation → Immutability

// Before: mutation function addItem(cart, item) { cart.items.push(item); cart.total += item.price; return cart; }

// After: immutable function addItem(cart, item) { return { ...cart, items: [...cart.items, item], total: cart.total + item.price }; }

Shared State → Pure Functions

// Before: shared state let counter = 0; function increment() { counter++; return counter; }

// After: pure function increment(counter) { return counter + 1; }

Nested Logic → Composition

// Before: nested function process(data) { const validated = validate(data); if (validated) { const transformed = transform(validated); return format(transformed); } return null; }

// After: composed (with pipe/flow) const process = pipe( validate, transform, format );

Detailed Patterns Reference

For comprehensive patterns including Option/Result types, composition helpers, currying, and TypeScript-specific techniques, see references/patterns.md.

Code Review Checklist

When reviewing, check for:

  • Functions return values (not void/undefined for logic)

  • No mutation of input parameters

  • Side effects isolated and clearly marked

  • Loops replaced with map/filter/reduce where clearer

  • Conditionals use early returns or ternaries for simple cases

  • Complex conditionals extracted to named predicates

  • State transformations are pure

  • Error handling uses Result/Either/Option patterns when available

Anti-Patterns to Flag

Anti-Pattern Refactor To

for loop with push map /filter /reduce

let with reassignment const with transformation

Nested callbacks Composition or async/await

null checks everywhere Option/Maybe type

try/catch everywhere Result/Either type

Class with mutable state Pure functions + data

Global variables Dependency injection

if/else chains Pattern matching or lookup tables

When NOT to Apply FP

  • Performance-critical hot paths where mutation is measurably faster

  • When the team/codebase has no FP experience (introduce gradually)

  • Simple scripts where FP adds complexity without benefit

  • When existing patterns in the repo are intentionally imperative

  • Legacy codebases where consistency matters more than FP purity

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

deslop-simplify-ai-code

No summary provided by upstream source.

Repository SourceNeeds Review
General

react-native-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

ui-engineer

No summary provided by upstream source.

Repository SourceNeeds Review