Toopo — utility functions with a public, executable contract

4 utility functions with a published contract: a signature, property-based invariants, and every edge case named and settled. The source is copied into your project.

# Toopo

Utility functions you copy into your project, each verified against a public, executable contract. Not a dependency: the source lands in your repository and it is yours.

A contract is the whole behavioural specification of one function — its signature, the invariants that must hold for every input, and every edge case named, settled and argued for. Anything that satisfies it can replace anything else that does, which is what makes an implementation a detail. The contract is what this project publishes; the code is what it hands you.

## 5 contracts

- ### [typescript/number/parse@1](typescript/number/parse@1/)

  Convert a string to a finite number, or null when the string is not a decimal number.

  toopo add number/parse
- ### [typescript/date/add@1](typescript/date/add@1/)

  Add a duration to a Date and get a new Date back, in UTC, without mutating the input, or null when the call cannot be answered exactly - with a named reason available beside it for a caller who needs to know which refusal it was.

  toopo add date/add
- ### [typescript/array/group-by@1](refused/)

  Partition an array into groups by a key computed from each element, keeping the input order everywhere and the key values exactly as the key function returned them.

  Considered and turned down — see what we refuse and why.
- ### [typescript/string/levenshtein@1](typescript/string/levenshtein@1/)

  Count the single-character insertions, deletions and substitutions that turn one string into the other, counting in Unicode code points.

  toopo add string/levenshtein
- ### [typescript/string/slugify@1](typescript/string/slugify@1/)

  Turn text into a URL-safe identifier: one lower-case run of letters, marks and digits per word, joined by single hyphens. The output is Unicode, not ASCII.

  toopo add string/slugify

## What we refuse

1 of these 5 was written in full and then turned down. What they were turned down for, and the measurement each decision rests on, is published beside them.

[What we refuse, and why](refused/)

## How we verify

A test suite that has never failed proves nothing. Every contract here is measured by breaking the implementation on purpose and requiring the suite to notice — and what those measurements did not catch is published beside what they did.

[How we verify, and what it does not prove](method/)

## What a contribution can be

An implementation, or an input where ours is wrong — never a contract. A contract is frozen for the life of its major version, and almost everything it settles is an address that can never move, so it is ours to keep rather than yours to send. An implementation freezes nothing: it competes under a contract that already exists, and that contract's own suite — public, and runnable by anyone — is what decides between it and ours. CONTRIBUTING.md in the repository says what can be received today and what cannot.
