| 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 |
Last active
December 23, 2025 19:46
-
-
Save sir-wabbit/96e391c74d768a850dd430f6edceca8e to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment