A Clojure utility library providing foundational functions for the Provisdom ecosystem. Offers error handling as data (anomalies), extended collection operations, map utilities, string manipulation, debugging helpers, and spec extensions.
Add to your deps.edn:
provisdom/utility-belt {:git/url "https://github.com/Provisdom/utility-belt.git"
:git/sha "..."}Error handling as data, based on Cognitect's anomaly approach. Treats errors as maps with categories rather than exceptions.
anomaly?- Test if value is an anomalyanomalous-let- Let binding that short-circuits on anomaliesex/ex!/ex?!- Convert anomalies to/throw exceptionsanomaly-try- Catch exceptions and convert to anomalieschain- Monadic chaining for anomaly-returning functionsrecover- Provide fallback values for anomalies
Function introspection using reflection to analyze function signatures at runtime.
arities- Returns vector of arity maps with::parameters(count) and::variadic?(boolean)min-arity- Minimum number of arguments the function acceptsmax-fixed-arity- Maximum fixed (non-variadic) arity, or nil if only variadicvariadic?- Returns true if function accepts variable argumentsaccepts-arity?- Check if function can be called with n arguments
Parallel processing with core.async.
thread- Execute functions in parallel with coordination modes and options:- Threading types:
:all,:and,:or,:first-success!!,:race!!,:any-ordered - Options:
:timeout-ms(max wait time),:allow-nil?(permit nil returns)
- Threading types:
thread-select- Parallel execution with custom result selection:- Options:
:timeout-ms,:min-successes(short-circuit after N successes),:progress-fn,:parallel?,:allow-nil?
- Options:
catch-error-or-exception- Wrap function to convert exceptions to anomalies (allows nil)catch-error-or-exception-or-nil- Wrap function to convert exceptions and nil to anomalies
Debugging utilities for REPL-driven development. All print-based macros respect *debug-enabled*.
*debug-enabled*- Dynamic var to globally enable/disable print-based debug outputdbg- Print and return expression valuedbg-pp- Likedbgbut uses pprint for nested datadbg-when- Conditional debug; only prints when predicate is truedbg-fn- Wrap function to trace its calls and returnsspy- Print labeled value and return itspy->- Debug version of->that prints each stepspy->>- Debug version of->>that prints each steptimed- Print execution time and return valuetap-dbg- Send value totap>and return ittap-spy- Send labeled value totap>and return ittap-timed- Send timing info totap>and return value
Extended Clojure core functionality for collections and bindings.
if-all-let/when-all-let- Multi-binding conditionals requiring all truthyif-some-let/when-some-let- Multi-binding conditionals requiring all non-nil (allows false)update-in-with-not-found-update-inwith custom default for missing keysinterleave-all- Interleave that consumes all elements from all collectionsreduce-kv-ext- Reduce with indices over multiple collectionsdeep-merge- Recursive map mergingindex-by- Group collection by unique key into mapfrequencies-by- Count occurrences after applying functionpartition-map- Split collection by predicate into [matches, non-matches]find-first- Find first element matching predicate (eager, stops early)dissoc-in- Dissociate a key at a nested path, removing empty parentsassoc-some- Likeassocbut skips nil valuesdistinct-by- Remove duplicates using a key functionindex-of- Find index of first element matching predicatesafe-nth- Likenthbut returns nil/default for out-of-boundskeep-kv- Likekeep-indexedwith (index, value) argument ordertake-until/drop-until- Like take-while/drop-while but inclusive of terminating element
Utilities for priority maps, sorted maps, and map manipulation.
Note: For basic map-over-keys/values operations, use Clojure 1.11+ core functions:
update-vals- map function over valuesupdate-keys- map function over keys
Functions provided:
priority-map/priority-map?- Priority map creation and testingsorted-map?/sorted-map-by?- Sorted map predicatessorted-map-monotonic?- Test for monotonically increasing valuesfilter-map/remove-map- Filter/remove map entries preserving map typesubmap?- Test if one map contains all entries of anotherselect-keys-by/remove-keys-by- Select/remove keys matching a predicateinvert-map- Swap keys and valuesmap-kv- Transform both keys and values simultaneouslyupdate-some- Likeupdatebut only if key exists
Nil-safe function composition and nil handling utilities.
ignore-nils/ignore-nils-fn- Remove nil args before calling functionanomaly-nils/anomaly-nils-fn- Return anomaly if any arg is nilnil-nils/nil-nils-fn- Return nil if any arg is nilcoalesce- Return first non-nil value (nil-safe alternative toor)default-nil- Return value or default if nil (nil-safe alternative toor)remove-nil-vals- Remove entries with nil values from a mapreplace-nil-vals- Replace nil values in a map with a defaultreplace-nils- Replace nils in sequence with values from another
Specs, predicates, and utilities for point-in-time sorted sequences. All predicates use O(n) algorithms.
Generic predicates (work on any seqable):
sorted?/sorted-by?- Test if sorted ascending (allows duplicates)strictly-sorted?/strictly-sorted-by?- Test if sorted ascending (no duplicates)sorted-desc?/sorted-desc-by?- Test if sorted descending (allows duplicates)strictly-sorted-desc?/strictly-sorted-desc-by?- Test if sorted descending (no duplicates)
Type-specific predicates:
seq-sorted?/seq-sorted-by?- Test if sequential is sortedlist-sorted?/list-sorted-by?- Test if list is sortedvector-sorted?/vector-sorted-by?- Test if vector is sorted
Spec macros:
list-sorted-of/list-sorted-by-of- Specs for sorted listsvector-sorted-of/vector-sorted-by-of- Specs for sorted vectors
Binary search (O(log n) on indexed collections):
binary-search/binary-search-by- Find index of element, or nilbinary-search-insertion-point/binary-search-insertion-point-by- Find insertion index
Utilities:
insert-sorted/insert-sorted-by- Insert into sorted vector maintaining ordermerge-sorted/merge-sorted-by- Merge two sorted sequences into sorted vector
Specs, predicates, and utilities for self-sorting sets.
Predicates:
sorted-set?/sorted-set-by?- Test if set is sorted
Spec macros:
sorted-set-of/sorted-set-by-of- Create specs for sorted sets (accepts:min-count,:max-count,:gen-max, etc.)
NavigableSet-style operations (like Java's NavigableSet):
floor- Greatest element <= value, or nilceiling- Least element >= value, or nillower- Greatest element < value, or nilhigher- Least element > value, or nilsubset- Elements in range [from, to)subset-inclusive- Elements in range [from, to]
String manipulation utilities complementing clojure.string.
substring- Safe substring with optional end indextrim-start/trim-end- Recursively remove prefix/suffixensure-prefix/ensure-suffix- Add prefix/suffix only if not already presentinsert- Insert substring at indexabbreviate- Truncate with ellipsistruncate-words- Truncate at word boundarytruncate-middle- Truncate keeping start and end (useful for paths)blank->nil- Convert blank strings to nilnormalize-whitespace- Collapse multiple whitespace to single spaceword-count- Count words in a stringcapitalize-words- Capitalize first letter of each wordpad-left/pad-right- Pad string to length with characterkebab->camel/camel->kebab- Convert between kebab-case and camelCasekebab->snake/snake->kebab- Convert between kebab-case and snake_case
Extensions to clojure.spec.alpha for enhanced spec definitions.
Note: This namespace shadows clojure.core/def, so use :refer-clojure :exclude [def] or alias it.
Enhanced spec definition:
def- Likes/defbut supports metadata maps and docstringsfdef- Likes/fdefbut supports:throwsclause for declaring exceptionsget-meta- Retrieve metadata map for a specspecs-with-meta- List all specs that have metadataclear-meta!- Remove metadata for a specthrowing-fdefs- Find all fdefs that declare:throws
(require '[provisdom.utility-belt.spec-ext :as spec-ext])
;; def with metadata
(spec-ext/def ::my-spec {:doc "A positive integer"} pos-int?)
;; fdef with :throws - declares which exceptions the function may throw
(spec-ext/fdef my-fn
:args (s/cat :x int?)
:ret string?
:throws [IllegalArgumentException ArithmeticException])
;; Use predicates for exception matching (e.g., anomaly exceptions)
(spec-ext/fdef risky-fn
:args (s/cat :x any?)
:ret map?
:throws [anomalies/anomaly-ex?])
;; Query metadata
(spec-ext/get-meta ::my-spec) ; => {:doc "A positive integer"}
(spec-ext/throwing-fdefs) ; => {my-fn [IllegalArgumentException ...]}The :throws clause integrates with provisdom.test.core/is-spec-check - during generative testing, exceptions matching the :throws spec are treated as valid behavior rather than test failures.
Copyright © 2016-2026 Provisdom Corp.
Distributed under the GNU Lesser General Public License version 3.0.