Skip to content

Instantly share code, notes, and snippets.

@sir-wabbit
Last active December 23, 2025 19:46
Show Gist options
  • Select an option

  • Save sir-wabbit/96e391c74d768a850dd430f6edceca8e to your computer and use it in GitHub Desktop.

Select an option

Save sir-wabbit/96e391c74d768a850dd430f6edceca8e to your computer and use it in GitHub Desktop.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment