Last active
December 23, 2025 19:46
-
-
Save sir-wabbit/96e391c74d768a850dd430f6edceca8e to your computer and use it in GitHub Desktop.
Revisions
-
sir-wabbit revised this gist
Dec 23, 2025 . 1 changed file with 19 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,26 +1,33 @@ NOTE: "complexity" is somewhat vaguely defined here. The real distinction is whether we - expect an immediate return, - expect some non-trivial work that is a function of input size or object size - expect I/O-bound work --- | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | "Expected failure" alternative | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | Small | N/A | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | | `from(x)` | **Convert/extract** from another type (possibly lossy) | No | Small | N/A | Yes (if conversion invalid) | `fromOrNull`, `tryFrom` | | `parse(text)` | Parse **textual representation** (format/grammar) | No | Scales with input size | N/A | Yes (`IllegalArgumentException`, parse exception) | `parseOrNull`, `tryParse` | | `decode(bytes)` | Parse **binary encoding** (wire format) | No | Scales with input size | N/A | Yes | `decodeOrNull`, `tryDecode` | | `deserialize(data)` | Rehydrate object from serialized form (often structured) | No (shouldn't) | Scales with input size | N/A | Yes | `tryDeserialize` | | `toX()` | **Produce** an `X` (conversion that may allocate/copy) | No | O(1)-O(n) depending on structure | No | Prefer no; if can fail, make it obvious | `toXOrNull`, `tryToX` | | `asX()` | **View/adapt/cast-like** reinterpretation (cheap) | No | O(1) | No | No (ideally) | `asXOrNull` | | `withX(...)` | Return a copy with one field changed (structural update) | No | O(1)-O(n) depending on structure | No | No (unless validating constraints) | `withXOrNull` | | `copy(...)` | Kotlin data-class copy semantics | No | O(1)-O(n) depending on structure | No | No | N/A | | `normalize()` (mutating) | Normalize in-place | No | Scales with the object size | Yes | Yes if invariants violated | `normalizedRememberingFailures()` no thanks | | `normalized()` (pure) | Return normalized copy | No | Scales with the object size | No | Same as above | `normalizedOrNull` | | `sort()` | In-place ordering | No | O(n log n) | Yes | No | `sorted()` | | `sorted()` | Return sorted copy | No | O(n log n) | No | No | N/A | | `applyX(...)` / `updateX(...)` | Mutating update with intent | No | O(1)-O(n) depending on structure | Yes | Yes | `tryUpdateX` | | `load...()` | Read from persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes (I/O exceptions, domain) | `tryLoad`, `loadOrNull` | | `save...()` | Write to persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes | `trySave` | | `fetch...()` | Network retrieval | Yes (network) | Unbounded / network-bound | No | Yes | `tryFetch: Result<T>` | | `send...()` / `publish...()` / `emit...()` | Outbound side effect | Yes | Unbounded / I/O-bound | No | Yes | `trySend` | | `now()` / `current...()` | Sample clock/system state | Yes-ish (system) | O(1) | No | Rarely | N/A | | `getX()` | Property-like access (no work) | No | O(1) | No | No | N/A | | `findX(...)` | Lookup/search (may return none) | No | O(log(n))-O(n) depending on structure | No | No | returns `T?` | | `requireX(...)` (guard) | Validate args (public API boundary) | No | O(1)-O(n) | No | Yes: `IllegalArgumentException` | Provide non-throwing validator | | `checkX(...)` (guard) | Validate invariants/state (internal) | No | O(1)-O(n) | No | Yes: `IllegalStateException` | Usually not needed | | `validate()` | Produce diagnostics about validity | No | O(n) | No | Prefer no | return `List<Error>` / `Validation` | -
sir-wabbit revised this gist
Dec 23, 2025 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | "Expected failure" alternative | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | O(1) or proportional to input size (validate/lookup) | N/A | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | | `from(x)` | **Convert/extract** from another type (possibly lossy) | No | O(1)-O(n) depending on conversion | N/A | Yes (if conversion invalid) | `fromOrNull`, `tryFrom` | | `parse(text)` | Parse **textual representation** (format/grammar) | No | O(n) in text length | N/A | Yes (`IllegalArgumentException`, parse exception) | `parseOrNull`, `tryParse` | @@ -15,10 +15,10 @@ | `sorted()` | Return sorted copy | No | O(n log n) | No | No | N/A | | `applyX(...)` / `updateX(...)` | Mutating update with intent | No | O(1)-O(n) | Yes | Yes | `tryUpdateX` | | `load...()` | Read from persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes (I/O exceptions, domain) | `tryLoad`, `loadOrNull` | | `save...()` | Write to persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes | `trySave` | | `fetch...()` | Network retrieval | Yes (network) | Unbounded / network-bound | No | Yes | `tryFetch: Result<T>` | | `send...()` / `publish...()` / `emit...()` | Outbound side effect | Yes | Unbounded / I/O-bound | No | Yes | `trySend` | | `now()` / `current...()` | Sample clock/system state | Yes-ish (system) | O(1) | No | Rarely | N/A | | `getX()` | Property-like access (no work) | No | O(1) | No | No | N/A | | `findX(...)` | Lookup/search (may return none) | No | O(1)-O(n) depending | No | No | returns `T?` | | `requireX(...)` (guard) | Validate args (public API boundary) | No | O(1)-O(n) | No | Yes: `IllegalArgumentException` | Provide non-throwing validator | -
sir-wabbit revised this gist
Dec 23, 2025 . 1 changed file with 23 additions and 23 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,27 +1,27 @@ | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | "Expected failure" alternative | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | O(1) or proportional to input size (validate/lookup) | N/A | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | | `from(x)` | **Convert/extract** from another type (possibly lossy) | No | O(1)-O(n) depending on conversion | N/A | Yes (if conversion invalid) | `fromOrNull`, `tryFrom` | | `parse(text)` | Parse **textual representation** (format/grammar) | No | O(n) in text length | N/A | Yes (`IllegalArgumentException`, parse exception) | `parseOrNull`, `tryParse` | | `decode(bytes)` | Parse **binary encoding** (wire format) | No | O(n) in bytes | N/A | Yes | `decodeOrNull`, `tryDecode` | | `deserialize(data)` | Rehydrate object from serialized form (often structured) | No (shouldn't) | Usually O(n) | N/A | Yes | `tryDeserialize` | | `toX()` | **Produce** an `X` (conversion that may allocate/copy) | No | O(1) or O(n) if copying | No | Prefer no; if can fail, make it obvious | `toXOrNull`, `tryToX` | | `asX()` | **View/adapt/cast-like** reinterpretation (cheap) | No | O(1) | No | No (ideally) | `asXOrNull` | | `withX(...)` | Return a copy with one field changed (structural update) | No | O(1)-O(n) depending on structure | No | No (unless validating constraints) | `withXOrNull` | | `copy(...)` | Kotlin data-class copy semantics | No | O(1) | No | No | N/A | | `normalize()` (mutating) | Normalize in-place | No | Usually O(n) | Yes | Yes if invariants violated | `normalizedRememberingFailures()` no thanks | | `normalized()` (pure) | Return normalized copy | No | Usually O(n) | No | Same as above | `normalizedOrNull` | | `sort()` | In-place ordering | No | O(n log n) | Yes | No | `sorted()` | | `sorted()` | Return sorted copy | No | O(n log n) | No | No | N/A | | `applyX(...)` / `updateX(...)` | Mutating update with intent | No | O(1)-O(n) | Yes | Yes | `tryUpdateX` | | `load...()` | Read from persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes (I/O exceptions, domain) | `tryLoad`, `loadOrNull` | | `save...()` | Write to persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes | `trySave` | | | `fetch...()` | Network retrieval | Yes (network) | Unbounded / network-bound | No | Yes | `tryFetch: Result<T>` | | | `send...()` / `publish...()` / `emit...()` | Outbound side effect | Yes | Unbounded / I/O-bound | No | Yes | `trySend` | | `now()` / `current...()` | Sample clock/system state | Yes-ish (system) | O(1) | No | Rarely | N/A | | | `getX()` | Property-like access (no work) | No | O(1) | No | No | N/A | | `findX(...)` | Lookup/search (may return none) | No | O(1)-O(n) depending | No | No | returns `T?` | | `requireX(...)` (guard) | Validate args (public API boundary) | No | O(1)-O(n) | No | Yes: `IllegalArgumentException` | Provide non-throwing validator | | `checkX(...)` (guard) | Validate invariants/state (internal) | No | O(1)-O(n) | No | Yes: `IllegalStateException` | Usually not needed | | `validate()` | Produce diagnostics about validity | No | O(n) | No | Prefer no | return `List<Error>` / `Validation` | | `validateOrThrow()` | Validate then throw on failure | No | O(n) | No | Yes | `validate()` | -
sir-wabbit revised this gist
Dec 23, 2025 . No changes.There are no files selected for viewing
-
sir-wabbit revised this gist
Dec 23, 2025 . 1 changed file with 18 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,27 +1,27 @@ | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | "Expected failure" alternative | Notes / examples | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | O(1) or proportional to input size (validate/lookup) | No | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | Good for "I already have the pieces." `Rgb.of(r,g,b)`, `TimeZone.of("Europe/Berlin")` | | `from(x)` | **Convert/extract** from another type (possibly lossy) | No | O(1)-O(n) depending on conversion | No | Yes (if conversion invalid) | `fromOrNull`, `tryFrom` | "x is already structured." `Instant.from(TemporalAccessor)` style` | | `parse(text)` | Parse **textual representation** (format/grammar) | No | O(n) in text length | No | Yes (`IllegalArgumentException`, parse exception) | `parseOrNull`, `tryParse` | Parsing anything. | | `decode(bytes)` | Parse **binary encoding** (wire format) | No | O(n) in bytes | No | Yes | `decodeOrNull`, `tryDecode` | Use for protobuf/msgpack/custom framing. Strong "this may fail" signal | | `deserialize(data)` | Rehydrate object from serialized form (often structured) | No (shouldn't) | Usually O(n) | No | Yes | `tryDeserialize` | Use when format isn't strictly "text parsing" but rehydration from structured data | | `toX()` | **Produce** an `X` (conversion that may allocate/copy) | No | O(1) or O(n) if copying | No | Prefer no; if can fail, make it obvious | `toXOrNull`, `tryToX` | `toString()` is the classic. If it can fail, don't hide it | | `asX()` | **View/adapt/cast-like** reinterpretation (cheap) | No | O(1) | No | No (ideally) | `asXOrNull` | Think "no real work, just a different lens." If it allocates, it shouldn't be `as` | | `withX(...)` | Return a copy with one field changed (structural update) | No | O(1)-O(n) depending on structure | No | No (unless validating constraints) | `withXOrNull` | For immutable types. If it can violate invariants, validate and possibly throw | | `copy(...)` | Kotlin data-class copy semantics | No | O(1) | No | No | N/A | Prefer using built-in `copy` over inventing ten `with...` methods | | `normalize()` (mutating) | Normalize in-place | No | Usually O(n) | Yes | Yes if invariants violated | `normalizedRememberingFailures()` no thanks | Pair with `normalized()` for pure version. Mutating name should be a verb | | `normalized()` (pure) | Return normalized copy | No | Usually O(n) | No | Same as above | `normalizedOrNull` | Pair naming makes mutation vs purity obvious | | `sort()` | In-place ordering | No | O(n log n) | Yes | No | `sorted()` | Kotlin precedent: `sort` mutates, `sorted` returns copy | | `sorted()` | Return sorted copy | No | O(n log n) | No | No | N/A | Avoid surprise side effects | | `applyX(...)` / `updateX(...)` | Mutating update with intent | No | O(1)-O(n) | Yes | Yes | `tryUpdateX` | Use when mutation is the point and you want it loud | | `load...()` | Read from persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes (I/O exceptions, domain) | `tryLoad`, `loadOrNull` | Names must admit touching the outside world | | `save...()` | Write to persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes | `trySave` | | | `fetch...()` | Network retrieval | Yes (network) | Unbounded / network-bound | No | Yes | `tryFetch: Result<T>` | | | `send...()` / `publish...()` / `emit...()` | Outbound side effect | Yes | Unbounded / I/O-bound | No | Yes | `trySend` | Your future self is not psychic | | `now()` / `current...()` | Sample clock/system state | Yes-ish (system) | O(1) | No | Rarely | N/A | | | `getX()` | Property-like access (no work) | No | O(1) | No | No | N/A | If it can block, parse, or do I/O, it should not be `get` | | `findX(...)` | Lookup/search (may return none) | No | O(1)-O(n) depending | No | No | returns `T?` | Conventional expectation: absence is normal, so use nullable | | `requireX(...)` (guard) | Validate args (public API boundary) | No | O(1)-O(n) | No | Yes: `IllegalArgumentException` | Provide non-throwing validator | Use Kotlin `require(...)` semantics: caller fault | | `checkX(...)` (guard) | Validate invariants/state (internal) | No | O(1)-O(n) | No | Yes: `IllegalStateException` | Usually not needed | If this fails in production, something is broken, not "invalid input" | | `validate()` | Produce diagnostics about validity | No | O(n) | No | Prefer no | return `List<Error>` / `Validation` | Better than throwing for routine invalid data | | `validateOrThrow()` | Validate then throw on failure | No | O(n) | No | Yes | `validate()` | Makes "throws" explicit without burying it | -
sir-wabbit revised this gist
Dec 23, 2025 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,3 @@ | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | “Expected failure” alternative | Notes / examples | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | O(1) or proportional to input size (validate/lookup) | No | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | Good for “I already have the pieces.” `Rgb.of(r,g,b)`, `TimeZone.of("Europe/Berlin")` | -
sir-wabbit created this gist
Dec 23, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ Here. A table that turns naming into something slightly less religious. | Name / Pattern | Intended use | I/O allowed | Typical complexity expectation | Can mutate `this` | Exceptions: allowed by default | “Expected failure” alternative | Notes / examples | | ------------------------------------------ | ------------------------------------------------------------------------------ | ---------------: | ---------------------------------------------------- | ----------------: | --------------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `of(...)` | Construct from **domain parts** or a **domain identifier** (validated factory) | No | O(1) or proportional to input size (validate/lookup) | No | Yes (`IllegalArgumentException` / domain exception) | `ofOrNull`, `tryOf: Result<T>` | Good for “I already have the pieces.” `Rgb.of(r,g,b)`, `TimeZone.of("Europe/Berlin")` | | `from(x)` | **Convert/extract** from another type (possibly lossy) | No | O(1)–O(n) depending on conversion | No | Yes (if conversion invalid) | `fromOrNull`, `tryFrom` | “x is already structured.” `Instant.from(TemporalAccessor)` style; your domain: `Money.from(BigDecimal)` | | `parse(text)` | Parse **textual representation** (format/grammar) | No | O(n) in text length | No | Yes (`IllegalArgumentException`, parse exception) | `parseOrNull`, `tryParse` | Text is the warning label. If input is free-form user text, prefer `parseOrNull/tryParse` | | `decode(bytes)` | Parse **binary encoding** (wire format) | No | O(n) in bytes | No | Yes | `decodeOrNull`, `tryDecode` | Use for protobuf/msgpack/custom framing. Strong “this may fail” signal | | `deserialize(data)` | Rehydrate object from serialized form (often structured) | No (shouldn’t) | Usually O(n) | No | Yes | `tryDeserialize` | Use when format isn’t strictly “text parsing” but rehydration from structured data | | `toX()` | **Produce** an `X` (conversion that may allocate/copy) | No | O(1) or O(n) if copying | No | Prefer no; if can fail, make it obvious | `toXOrNull`, `tryToX` | `toString()` is the classic. If it can fail, don’t hide it | | `asX()` | **View/adapt/cast-like** reinterpretation (cheap) | No | O(1) | No | No (ideally) | `asXOrNull` | Think “no real work, just a different lens.” If it allocates, it shouldn’t be `as` | | `withX(...)` | Return a copy with one field changed (structural update) | No | O(1)–O(n) depending on structure | No | No (unless validating constraints) | `withXOrNull` | For immutable types. If it can violate invariants, validate and possibly throw | | `copy(...)` | Kotlin data-class copy semantics | No | O(1) | No | No | N/A | Prefer using built-in `copy` over inventing ten `with...` methods | | `normalize()` (mutating) | Normalize in-place | No | Usually O(n) | Yes | Yes if invariants violated | `normalizedRememberingFailures()` no thanks | Pair with `normalized()` for pure version. Mutating name should be a verb | | `normalized()` (pure) | Return normalized copy | No | Usually O(n) | No | Same as above | `normalizedOrNull` | Pair naming makes mutation vs purity obvious | | `sort()` | In-place ordering | No | O(n log n) | Yes | No | `sorted()` | Kotlin precedent: `sort` mutates, `sorted` returns copy | | `sorted()` | Return sorted copy | No | O(n log n) | No | No | N/A | Avoid surprise side effects | | `applyX(...)` / `updateX(...)` | Mutating update with intent | No | O(1)–O(n) | Yes | Yes | `tryUpdateX` | Use when mutation is the point and you want it loud | | `load...()` | Read from persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes (I/O exceptions, domain) | `tryLoad`, `loadOrNull` | Names must admit touching the outside world | | `save...()` | Write to persistent storage | Yes (disk) | Unbounded / I/O-bound | Usually No | Yes | `trySave` | “save” implies side effects. Good | | `fetch...()` | Network retrieval | Yes (network) | Unbounded / network-bound | No | Yes | `tryFetch: Result<T>` | Don’t name this `getUser()` unless you enjoy lying | | `send...()` / `publish...()` / `emit...()` | Outbound side effect | Yes | Unbounded / I/O-bound | No | Yes | `trySend` | Make the effect explicit. Your future self is not psychic | | `now()` / `current...()` | Sample clock/system state | Yes-ish (system) | O(1) | No | Rarely | N/A | Non-deterministic by definition. Don’t disguise it as pure | | `getX()` | Property-like access (no work) | No | O(1) | No | No | N/A | If it can block, parse, or do I/O, it should not be `get` | | `findX(...)` | Lookup/search (may return none) | No | O(1)–O(n) depending | No | No | returns `T?` | Conventional expectation: absence is normal, so use nullable | | `requireX(...)` (guard) | Validate args (public API boundary) | No | O(1)–O(n) | No | Yes: `IllegalArgumentException` | Provide non-throwing validator | Use Kotlin `require(...)` semantics: caller fault | | `checkX(...)` (guard) | Validate invariants/state (internal) | No | O(1)–O(n) | No | Yes: `IllegalStateException` | Usually not needed | If this fails in production, something is broken, not “invalid input” | | `validate()` | Produce diagnostics about validity | No | O(n) | No | Prefer no | return `List<Error>` / `Validation` | Better than throwing for routine invalid data | | `validateOrThrow()` | Validate then throw on failure | No | O(n) | No | Yes | `validate()` | Makes “throws” explicit without burying it |