taoensso.encore

Extended core library for Clojure/Script that emphasizes:
  * Cross-platform API
  * Flexibility
  * Performance
  * Backwards compatibility

This lib's mostly for my own use and for advanced users that feel
comfortable reading this source. Not providing much beginner-oriented
documentation for this, sorry.

Common naming conventions used across my libs:
  **foo** - Dynamic var
  foo!    - Fn with side-effects, or that should otherwise be used cautiously
  foo?    - Truthy val or fn that returns truthy val
  foo!?   - Fn that has side-effects (or requires caution) and that return
            a truthy val. Note: !?, not ?!
  foo$    - Fn that's notably expensive to compute (e.g. hits db)
  foo_    - Derefable val (e.g. atom, volatile, delay, etc.)
  foo__   - Derefable in a derefable (e.g. delay in an atom), etc.
  _       - Unnamed val
  _foo    - Named but unused val
  ?foo    - Optional val (emphasize that val may be nil)
  foo*    - A variation of `foo` (e.g. `foo*` macro vs `foo` fn)
  foo'    - ''
  -foo    - Public implementation detail or intermediate (e.g. uncoerced) val
  >foo    - Val "to   foo" (e.g. >sender, >host), or fn to  put/coerce/transform
  <foo    - Val "from foo" (e.g. <sender, <host), or fn to take/coerce/transform
  ->foo   - Fn to put/coerce/transform

Type affixes may be used for clarity:
  <prefix>-<name>  - m-users,   v-users,   n-users,    etc. (also nusers when unambiguous)
  <name>-<postfix> - users-map, users-vec, user-count, etc.

Regarding name heirarchy:
  When there's a significant num of syms with a meaningful hierarchy,
  prefer names with descending hierarchy to emphasize structure and
  related groups/functionality, e.g.:
    `user-add`, `user-remove`, `user-mod` vs
    `add-user`, `remove-user`, `mod-user`, etc.

Commit message tags (in priority order):
  [wip]   - Work-in-progress (still under development)

  [mod]   - Modify     behaviour (=>          breaking), [mod!], [mod!!], etc. for attention
  [fix]   - Fix broken behaviour (=> usu. non-breaking)
  [new]   - Add new    behaviour (=>      non-breaking)

  [doc]   - Documentation changes besides those better labelled as [mod], [fix], or [new]
  [nop]   - Other non-breaking changes (to implementation details, non-code changes, etc.)

  [x] [y] - Single commit with multiple tags (in priority order), try avoid

Example commit messages:
  v1.0.0 (2022-01-27) ; Tagged release
  [new] [#122] Add new feature x (@contributor)

Version numbers:
  Ver tables:  X.Y.Z (without backticks)
     Min ver: vX.Y.Z+
   Elsewhere: vX.Y.Z

<*

macro

clj

cljs

(<* x y z)

<=*

macro

clj

cljs

(<=* x y z)

>*

macro

clj

cljs

(>* x y z)

>=*

macro

clj

cljs

(>=* x y z)

a-utf8-str

clj

cljs

Example UTF8 string for tests, etc.

abbreviate-ns

clj

cljs

added in Encore v3.68.0 (2023-09-25)

(abbreviate-ns x)(abbreviate-ns n-full x)
Give any nameable type (string, keyword, symbol), returns the same
type with at most `n-full` (default 1) unabbreviated namespace parts.

Example:
  (abbreviate-ns 0  :foo.bar/baz)   => :f.b/baz
  (abbreviate-ns 1  'foo.bar/baz)   => 'f.bar/baz
  (abbreviate-ns 2 "foo.bar/baz") => "foo.bar/baz"

abs

clj

cljs

(abs n)

after-timeout

macro

clj

cljs

(after-timeout msecs & body)
Alpha, subject to change.
Returns a TimeoutFuture that will execute body after timeout.
Body must be non-blocking or cheap.

ajax-call

cljs

added in Encore v3.74.0 (2023-11-06)

(ajax-call url {:keys [method params headers timeout-ms resp-type with-credentials? xhr-pool xhr-cb-fn xhr-timeout-ms], :as opts, :or {method :get, timeout-ms 10000, resp-type :auto, xhr-pool default-xhr-pool_, xhr-timeout-ms 2500}} callback-fn)
Queues a lightweight Ajax call with Google Closure's `goog.net.XhrIo` and
returns nil, or the resulting `goog.net.XhrIo` instance if one was
immediately available from the XHR pool:

  (ajax-call
    "http://localhost:8080/my-post-route" ; Endpoint URL

    {:method     :post ; ∈ #{:get :post :put}
     :resp-type  :text ; ∈ #{:auto :edn :json :xml :text}

     :params     {:username "Rich Hickey" :type "Awesome"} ; Request params
     :headers    {"Content-Type" "text/plain"} ; Request headers

     :timeout-ms 7000
     :with-credentials? false ; Enable if using CORS (requires xhr v2+)

     :xhr-pool       my-xhr-pool ; Optional `goog.net.XhrIoPool` instance or delay
     :xhr-cb-fn      (fn [xhr])  ; Optional fn to call with `XhrIo` from pool when available
     :xhr-timeout-ms 2500        ; Optional max msecs to wait on pool for `XhrIo`
    }

    (fn ajax-callback-fn [resp-map]
      (let [{:keys [success? ?status ?error ?content ?content-type]} resp-map]
        ;; ?status ; ∈ #{nil 200 404 ...}, non-nil iff server responded
        ;; ?error  ; ∈ #{nil <http-error-status-code> <exception> :timeout
                         :abort :http-error :exception :xhr-pool-depleted}
        (js/alert (str "Ajax response: " resp-map)))))

approx==

clj

cljs

(approx== x y)(approx== signf x y)

as-?bool

clj

cljs

(as-?bool x)

as-?email

clj

cljs

(as-?email ?s)(as-?email max-len ?s)

as-?float

clj

cljs

(as-?float x)

as-?inst

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(as-?inst x)
Returns given ?arg as platform instant (`java.time.Instant` or `js/Date`), or nil.

as-?int

clj

cljs

(as-?int x)

as-?kw

clj

cljs

(as-?kw x)

as-?name

clj

cljs

(as-?name x)

as-?nat-float

clj

cljs

(as-?nat-float x)

as-?nat-int

clj

cljs

(as-?nat-int x)

as-?nblank

clj

cljs

(as-?nblank x)

as-?nblank-trim

clj

cljs

(as-?nblank-trim x)

as-?nemail

clj

cljs

(as-?nemail ?s)(as-?nemail max-len ?s)

as-?nempty-str

clj

cljs

(as-?nempty-str x)

as-?nzero

clj

cljs

(as-?nzero x)

as-?pnum

clj

cljs

(as-?pnum x)

as-?pos-float

clj

cljs

(as-?pos-float x)

as-?pos-int

clj

cljs

(as-?pos-int x)

as-?qname

clj

cljs

(as-?qname x)

as-?rnum

clj

cljs

(as-?rnum x)

as-?udt

clj

cljs

(as-?udt x)
Returns given ?arg as (pos/neg) milliseconds since Unix epoch, or nil.

as-bool

clj

cljs

(as-bool x)

as-email

clj

cljs

(as-email x)(as-email n x)

as-float

clj

cljs

(as-float x)

as-inst

clj

cljs

(as-inst x)

as-int

clj

cljs

(as-int x)

as-kw

clj

cljs

(as-kw x)

as-name

clj

cljs

(as-name x)

as-nat-float

clj

cljs

(as-nat-float x)

as-nat-int

clj

cljs

(as-nat-int x)

as-nblank

clj

cljs

(as-nblank x)

as-nblank-trim

clj

cljs

(as-nblank-trim x)

as-nemail

clj

cljs

(as-nemail x)(as-nemail n x)

as-nempty-str

clj

cljs

(as-nempty-str x)

as-nzero

clj

cljs

(as-nzero x)

as-pnum

clj

cljs

(as-pnum x)

as-pnum!

clj

cljs

(as-pnum! x)

as-pnum-complement

clj

cljs

(as-pnum-complement x)

as-pos-float

clj

cljs

(as-pos-float x)

as-pos-int

clj

cljs

(as-pos-int x)

as-qname

clj

cljs

(as-qname x)

as-rnum

clj

cljs

(as-rnum x)

as-rnum!

clj

cljs

(as-rnum! x)

as-udt

clj

cljs

(as-udt x)

assert-min-encore-version

clj

cljs

(assert-min-encore-version min-version)
Version check for dependency conflicts, etc.

assoc-nx

clj

cljs

(assoc-nx m k v)(assoc-nx m m-kvs)(assoc-nx m k v & kvs)
Assocs each kv to given ?map iff its key doesn't already exist.

assoc-some

clj

cljs

(assoc-some m k v)(assoc-some m m-kvs)(assoc-some m k v & kvs)
Assocs each kv to given ?map iff its value is not nil.

assoc-when

clj

cljs

(assoc-when m k v)(assoc-when m m-kvs)(assoc-when m k v & kvs)
Assocs each kv to given ?map iff its val is truthy.

atom?

clj

cljs

(atom? x)

bench

macro

clj

cljs

(bench nlaps opts & body)

binding

macro

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(binding bindings & body)
For Clj: faster version of `core/binding`.
For Cljs: identical to `core/binding`.

boolean?

clj

cljs

(boolean? x)

cache

clj

cljs

added in Encore v3.36.0 (2022-11-18)

(cache f)(cache {:keys [size ttl-ms gc-every], :as opts} f)
Returns a cached version of given referentially transparent function `f`.

Like `core/memoize` but:
  - Often faster, depending on options.
  - Prevents race conditions on writes.
  - Supports cache invalidation by prepending args with:
    - `:cache/del`   ; Delete cached item for subsequent args, returns nil.
    - `:cache/fresh` ; Renew  cached item for subsequent args, returns new val.

  - Supports options:
    - `ttl-ms` ; Expire cached items after <this> many msecs.
    - `size`   ; Restrict cache size to <this> many items at the next garbage
               ; collection (GC).

    - `gc-every` ; Run garbage collection (GC) approximately once every
                 ; <this> many calls to cached fn. If unspecified, GC rate
                 ; will be determined automatically based on `size`.

See also `defn-cached`, `fmemoize`, `memoize-last`.

call-after-timeout

clj

cljs

(call-after-timeout msecs f)(call-after-timeout impl_ msecs f)
Alpha, subject to change.
Returns a TimeoutFuture that will execute `f` after given msecs.

Does NOT do any automatic binding conveyance.

Performance depends on the provided timer implementation (`impl_`).
The default implementation offers O(logn) add, O(1) cancel, O(1) tick.

See `ITimeoutImpl` for extending to arbitrary timer implementations.

can-meta?

clj

cljs

(can-meta? x)

case-eval

macro

clj

cljs

(case-eval expr & clauses)
Like `case` but test expressions are evaluated for their compile-time value.

case-insensitive-str=

clj

cljs

added in Encore v3.25.0 (2022-10-13)

(case-insensitive-str= s1 s2)
Returns true iff given strings are equal, ignoring case.

catching

macro

clj

cljs

(catching expr)(catching error-type expr)
Terse, cross-platform (try* expr (catch :all _)).
See also `try*` for more flexibility.

catching-rf

clj

cljs

added in Encore v3.32.0 (2022-11-07)

(catching-rf rf)(catching-rf error-fn rf)
Returns wrapper around given reducing function `rf` so that if `rf`
throws, (error-fn <thrown-error> <contextual-data>) will be called.

The default `error-fn` will rethrow the original error, wrapped in
extra contextual information to aid debugging.

See also `catching-xform`.

catching-xform

clj

cljs

added in Encore v3.32.0 (2022-11-07)

(catching-xform error-fn xform)(catching-xform xform)
Like `catching-rf`, but applies to a transducer (`xform`).

Makes debugging transductions much easier by greatly improving
the information provided in any errors thrown by `xform` or the
reducing fn:

  (transduce
    (catching-xform (comp (filter even?) (map inc))) ; Modified xform
    <reducing-fn>
    <...>)

chan?

clj

cljs

(chan? x)
Returns true iff given a `clojure.core.async` channel.

chance

clj

cljs

(chance prob)
Returns true with given probability ∈ ℝ[0,1].

check-all

macro

clj

cljs

(check-all test)(check-all test & more)
Returns all logical false/throwing expressions (ids/forms), or nil.

check-some

macro

clj

cljs

(check-some test & more)(check-some test)
Returns first logical false/throwing expression (id/form), or nil.

clamp

clj

cljs

(clamp nmin nmax n)

clamp*

macro

clj

cljs

(clamp* nmin nmax n)

clamp-float

clj

cljs

(clamp-float nmin nmax n)

clamp-int

clj

cljs

(clamp-int nmin nmax n)

comp-middleware

clj

cljs

added in Encore v3.106.0 (2024-05-01)

(comp-middleware fs)(comp-middleware f1 f2)(comp-middleware f1 f2 f3)(comp-middleware f1 f2 f3 & fs)
Returns a single (composite) unary fn that applies all given unary fns
sequentially (left->right!: f1, f2, ...). If any given fn returns nil, the
returned composite fn immediately returns nil:

  ((comp-middleware inc #(* % 2) inc) 1) => 5 ; (inc (* (inc 1) 2))
  ((comp-middleware inc (fn [_] nil) (fn [_] (throw (Exception. "Never thrown!")))) 1) => nil

Useful for composing Ring-style middleware fns.

compile-if

macro

clj

cljs

(compile-if test then)(compile-if test then else)
Evaluates `test`. If it returns logical true (and doesn't throw), expands
to `then`, otherwise expands to `else`.

compile-when

macro

clj

cljs

(compile-when test & body)

cond

macro

clj

cljs

(cond & clauses)
Supersets `core/cond` functionality. Like `core/cond` but supports implicit
final `else` clause, and special clause keywords for advanced behaviour:

(cond
  :let     [x   "x"] ; Establish let     binding/s for remaining forms
  :binding [*x* "x"] ; Establish dynamic binding/s for remaining forms
  :do      (println (str "x value: " x)) ; Eval expr for side-effects

  :if-let [y "y"
           z nil]
  "y and z were both truthy"

  :if-some [y "y"
            z nil]
  "y and z were both non-nil")

`:let` support inspired by <https://github.com/Engelberg/better-cond>.
Simple, flexible way to eliminate deeply-nested control flow code.

cond!

macro

clj

cljs

(cond! & clauses)
Like `cond` but throws on non-match like `case` and `condp`.

conj-some

clj

cljs

(conj-some)(conj-some coll)(conj-some coll x)(conj-some coll x & more)
Conjoins each non-nil value.

conj-when

clj

cljs

(conj-when)(conj-when coll)(conj-when coll x)(conj-when coll x & more)
Conjoins each truthy value.

const-str=

clj

cljs

(const-str= s1 s2)
Constant-time string equality checker.
Useful to prevent timing attacks, etc.

contains-in?

clj

cljs

(contains-in? coll ks k)(contains-in? coll ks)

convey-reduced

clj

cljs

(convey-reduced x)

count-words

clj

cljs

(count-words s)

counter

clj

cljs

(counter)(counter init)
Returns a fast atomic `Counter` with `init` initial integer value with:
- @counter           => Return current val
- (counter)          => Add 1 and return old val
- (counter n)        => Add n and return old val
- (counter action n) => Experimental, action ∈
    {:add :set :set-get :get-set :get-add :add-get}.

Counter

cljs

declare-remote

macro

clj

cljs

(declare-remote & syms)
Declares given ns-qualified symbols, preserving metadata.
Clj only. Useful for circular dependencies.

def*

macro

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(def* sym & args)
Like `core/def` but supports attrs map.

defalias

macro

clj

cljs

(defalias src)(defalias alias src)(defalias alias src alias-attrs)(defalias alias src alias-attrs alias-body)
Defines a local alias for the var identified by given qualified
source symbol: (defalias my-map clojure.core/map), etc.

Source var's metadata will be preserved (docstring, arglists, etc.).
Changes to Clj source var's value will also be applied to alias.
See also `defaliases`.

defaliases

macro

clj

cljs

added in Encore v3.58.0 (2023-04-09)

(defaliases {:keys [alias src attrs body]} ...)
Bulk version of `defalias`.
Takes source symbols or {:keys [alias src attrs body]} maps:
  (defaliases
    {:alias my-map, :src map, :attrs {:doc "My `map` alias"}}
    {:alias my-vec, :src vec, :attrs {:doc "My `vec` alias"}})

default-timeout-impl_

clj

cljs

Simple one-timeout timeout implementation provided by platform timer.
O(logn) add, O(1) cancel, O(1) tick. Fns must be non-blocking or cheap.
Similar efficiency to core.async timers (binary heap vs DelayQueue).

DefaultTimeoutImpl

cljs

defn-cached

macro

clj

cljs

added in Encore v3.36.0 (2022-11-18)

(defn-cached sym cache-opts & body)
Defines a cached function.
Like (def <sym> (cache <cache-opts> <body...>)), but preserves
:arglists (arity) metadata as with `defn`:

  (defn-cached ^:private my-fn {:ttl-ms 500}
    "Does something interesting, caches resultes for 500 msecs"
    [n]
    (rand-int n))

defonce

macro

clj

cljs

(defonce sym & args)
Like `core/defonce` but supports docstring and attrs map.

defstub

macro

clj

cljs

(defstub sym)
Experimental, subject to change without notice!!
Declares a stub var that can be initialized from any namespace with
`unstub-<stub-name>`.

Decouples a var's declaration (location) and its initialization (value).
Useful for defining vars in a shared ns from elsewhere (e.g. a private
or cyclic ns).

deprecated

macro

clj

cljs

(deprecated & body)
Elides body when `taoensso.elide-deprecated` JVM property or
`TAOENSSO_ELIDE_DEPRECATED` environment variable is ∈ #{"true" "TRUE"}.

derefable?

clj

cljs

(derefable? x)

dissoc-in

clj

cljs

(dissoc-in m ks dissoc-k)(dissoc-in m ks dissoc-k & more)(dissoc-in m ks)

distinct-elements?

clj

cljs

(distinct-elements? x)

doto-cond

macro

clj

cljs

(doto-cond [sym x] & clauses)
Cross between `doto`, `cond->` and `as->`.

editable?

clj

cljs

(editable? x)

encore-version

clj

cljs

ensure-set

clj

cljs

(ensure-set x)

ensure-vec

clj

cljs

(ensure-vec x)

error?

clj

cljs

(error? x)
Returns true iff given platform error (`Throwable` or `js/Error`).

ex-cause

clj

cljs

added in Encore v3.41.0 (2022-12-03)

(ex-cause x)
Same as `core/ex-cause` (added in Clojure v1.10).

ex-data

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(ex-data x)
Same as `core/ex-data` (added in Clojure v1.4).

ex-message

clj

cljs

added in Encore v3.41.0 (2022-12-03)

(ex-message x)
Same as `core/ex-message` (added in Clojure v1.10).

ex-root

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(ex-root x)
Returns root cause of given platform error.

exp-backoff

clj

cljs

(exp-backoff n-attempt)(exp-backoff n-attempt {:keys [min max factor], :or {factor 1000}})
Returns binary exponential backoff value for n<=36.

explode-keyword

clj

cljs

(explode-keyword k)

fast-merge

clj

cljs

(fast-merge maps)(fast-merge m1 m2)(fast-merge m1 m2 m3)(fast-merge m1 m2 m3 m4)
Like `core/merge` but faster.
Doesn't support zero arity, single arity case takes a collection of maps.

filter-keys

clj

cljs

(filter-keys key-pred m)
Returns given ?map, retaining only keys for which (key-pred <key>) is truthy.

filter-vals

clj

cljs

(filter-vals val-pred m)
Returns given ?map, retaining only keys for which (val-pred <val>) is truthy.

finite-num?

clj

cljs

(finite-num? x)
Returns true iff given a number (of standard type) that is:
finite (excl. NaN and infinities).

float?

clj

cljs

(float? x)
Returns true iff given a number (of standard type) that is:
a fixed-precision floating-point (incl. NaN and infinities).

fmemoize

clj

cljs

(fmemoize f)
For Clj: fastest possible memoize. Non-racey, 0-7 arity only.
For Cljs: same as `core/memoize`.

force-ref

clj

cljs

(force-ref x)
Like `force` for refs.

force-var

clj

cljs

(force-var x)
Like `force` for vars.

format

clj

cljs

(format fmt & args)
Like `core/format` but:
* Returns "" when fmt is nil rather than throwing an NPE.
* Formats nil as "nil" rather than "null".
* Provides ClojureScript support via goog.string.format (this has fewer
  formatting options than Clojure's `format`!).

format*

clj

cljs

(format* fmt args)(format* xform fmt args)

format-inst

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(format-inst inst)
Takes a platform instant (`java.time.Instant` or `js/Date`) and
returns a formatted human-readable string in `ISO8601` format
(`YYYY-MM-DDTHH:mm:ss.sssZ`), e.g. "2011-12-03T10:15:130Z".

format-inst-fn

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(format-inst-fn)(format-inst-fn {:keys [formatter]})
Experimental, subject to change without notice.

Returns a (fn format [instant]) that:
  - Takes a platform instant (`java.time.Instant` or `js/Date`).
  - Returns a formatted human-readable instant string.

Options:
  `:zone` (Clj only) `java.time.ZoneOffset` (defaults to UTC).
  `:formatter`
    `java.time.format.DateTimeFormatter` (Clj) or
    `goog.i18n.DateTimeFormat` (Cljs),

    Defaults to `ISO8601` formatter (`YYYY-MM-DDTHH:mm:ss.sssZ`),
    e.g.: "2011-12-03T10:15:130Z".

format-nsecs

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(format-nsecs nanosecs)
Returns given nanoseconds (long) as formatted human-readable string.
Example outputs: "1.00m", "4.20s", "340ms", "822μs", etc.

format-query-string

clj

cljs

(format-query-string m)

future*

macro

clj

cljs

added in Encore v3.72.0 (2023-10-24)

(future* form)(future* executor-service form)
Experimental, subject to change without notice!
Like `future` but supports use of given custom
`java.util.concurrent.ExecutorService`.

Will default to using JVM 21+ virtual threads when possible,
otherwise an unbounded fixed daemon thread pool.

See also `future-call`, `virtual-executor`, `pool-executor`.

get*

macro

clj

cljs

added in Encore v3.82.0 (2024-02-23)

(get* m k)(get* m k not-found)(get* m k1 k2 not-found)(get* m k1 k2 k3 not-found)
Macro version of `get` that:

  1. Avoids unnecessary evaluation of `not-found`.
     Useful when `not-found` is expensive or contains side-effects.

  2. Supports multiple prioritized keys (k1, k2, etc.). Returns val for first
     key that exists in map. Useful for key aliases or fallbacks.

Equivalent to:

  (cond
    (contains? m k1) (get m k1)
    (contains? m k2) (get m k2)
    ...
    :else            not-found)

get-env

macro

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(get-env {:keys [as default return], :or {as :str, return :value}} spec)
Flexible cross-platform util for embedding a config value during
macro expansion. Used by other Taoensso libraries.

Given a const kw/string id or vector of desc-priority alternative ids,
parse and return the first of the following that exists:
  - JVM         property value   for id
  - Environment variable value   for id
  - Classpath   resource content for id

Ids may include optional segment in `<>` tag (e.g. `<.edn>`).
Ids may include `<.?platform.?>` tag for auto replacement, useful
for supporting platform-specific config.

Search order: desc by combined [alt-index platform(y/n) optional(y/n)].

So (get-env {:as :edn} [:my-app/alt1<.platform><.edn> :my-app/alt2])
will parse and return the first of the following that exists:

  1. Alt1 +platform +optional (.edn suffix)
    1a. `my-app.alt1.clj.edn` JVM         property value
    1b. `MY_APP_ALT1_CLJ_EDN` environment variable value
    1c. `my-app.alt1.clj.edn` classpath   resource content

  2. Alt1 +platform -optional (.edn suffix)
    2a. `my-app.alt1.clj`     JVM         property value
    2b. `MY_APP_ALT1_CLJ`     environment variable value
    2c. `my-app.alt1.clj`     classpath   resource content

  3. Alt1 -platform +optional (.edn suffix)
    3a. `my-app.alt1.edn`     JVM         property value
    3b. `MY_APP_ALT1_EDN`     environment variable value
    3c. `my-app.alt1.edn`     classpath   resource content

  4. Alt1 -platform -optional (.edn suffix)
    4a. `my-app.alt1`         JVM         property value
    4b. `MY_APP_ALT1`         environment variable value
    4c. `my-app.alt1`         classpath   resource content

  5. Alt2
    5a. `my-app.alt2`         JVM         property value
    5b. `MY_APP_ALT2`         environment variable value
    5c. `my-app.alt2`         classpath   resource content

Options:
  `:as`      - Parse found value as given type ∈ #{:str :bool :edn} (default `:str`).
  `:default` - Fallback to return unparsed if no value found during search (default `nil`).
  `:return`  - Return type ∈ #{:value :map :explain} (default `:value`).

Resulting config value must be something that can be safely embedded in code during
macro-expansion. Symbols in edn will be evaluated during expansion.

TIP!: Use the {:return :explain} option in tests or at the REPL to verify/inspect
resulting config value, config source, and specific search order of prop/env/res ids.

get-substr-by-idx

clj

cljs

(get-substr-by-idx s start-idx)(get-substr-by-idx s start-idx end-idx)
Returns ?substring from given string.

Like `subs` but:
  - Provides consistent clj/s behaviour.
  - Never throws (snaps to valid indexes).
  - Indexes may be -ive (=> indexed from end of string).

Returns nil when requested substring would be empty.

get-substr-by-len

clj

cljs

(get-substr-by-len s start-idx)(get-substr-by-len s start-idx sub-len)
Returns ?substring from given string.
Like `get-substr-by-idx`, but takes a substring-length 3rd argument.

get-subvec

clj

cljs

(get-subvec v start)(get-subvec v start end)
Like `subvec` but never throws (snaps to valid start and end indexes).

get-subvector

clj

cljs

(get-subvector v start)(get-subvector v start length)
Like `get-subvec` but:
- Takes `length` instead of `end` (index).
- -ive `start` => index from right of vector.

get-truss-data

clj

cljs

(get-truss-data)
Returns current value of dynamic assertion data.

get-win-loc

cljs

(get-win-loc)
Returns current window location as
{:keys [href protocol hostname host pathname search hash]}.

get1

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(get1 m k)(get1 m k not-found)(get1 m k1 k2 not-found)(get1 m k1 k2 k3 not-found)
Like `get` but returns val for first key that exists in map.
Useful for key aliases or fallbacks. See also `get*`.

have

macro

clj

cljs

(have x)(have pred (:in) x)(have pred (:in) x & more-xs)
Takes a pred and one or more vals. Tests pred against each val,
trapping errors. If any pred test fails, throws a detailed assertion error.
Otherwise returns input val/vals for convenient inline-use/binding.

Respects *assert* value so tests can be elided from production for zero
runtime costs.

Provides a small, simple, flexible feature subset to alternative tools like
clojure.spec, core.typed, prismatic/schema, etc.

  ;; Will throw a detailed error message on invariant violation:
  (fn my-fn [x] (str/trim (have string? x)))

You may attach arbitrary debug info to assertion violations like:
  `(have string? x :data {:my-arbitrary-debug-info "foo"})`

Re: use of Truss assertions within other macro bodies:
  Due to CLJ-865, call site information (e.g. line number) of
  outer macro will unfortunately be lost.

  See `keep-callsite` util for a workaround.

See also `have?`, `have!`.

have!

macro

clj

cljs

(have! x)(have! pred (:in) x)(have! pred (:in) x & more-xs)
Like `have` but ignores *assert* value (so can never be elided). Useful
for important conditions in production (e.g. security checks).

have!?

macro

clj

cljs

(have!? x)(have!? pred (:in) x)(have!? pred (:in) x & more-xs)
Specialized cross between `have?` and `have!`. Not used often but can be
handy for semantic clarification and/or to improve multi-val performance
when the return vals aren't necessary.

**WARNING**: Do NOT use in :pre/:post conds since those are ALWAYS subject
to *assert*, directly contradicting the intention of the bang (`!`) here.

have-core-async?

clj

cljs

Is `clojure.core.async` present (not necessarily loaded)?

have-telemere?

clj

cljs

added in Encore v3.68.0 (2023-09-25)

Is `taoensso.telemere` present (not necessarily loaded)?

have?

macro

clj

cljs

(have? x)(have? pred (:in) x)(have? pred (:in) x & more-xs)
Like `have` but returns `true` on successful tests. In particular, this
can be handy for use with :pre/:post conditions. Compare:
  (fn my-fn [x] {:post [(have  nil? %)]} nil) ; {:post [nil]} FAILS
  (fn my-fn [x] {:post [(have? nil? %)]} nil) ; {:post [true]} passes as intended

ident?

clj

cljs

(ident? x)

identical-kw?

macro

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(identical-kw? x y)
Returns true iff two keywords are identical.
Portable and maximally fast.
  For Clj  this expands to: `(identical?         x y)`
  For Cljs this expands to: `(keyword-identical? x y)`

if-clj

macro

clj

cljs

(if-clj then & [else])

if-cljs

macro

clj

cljs

(if-cljs then & [else])

if-let

macro

clj

cljs

(if-let bindings then)(if-let bindings then else)
Supersets `core/if-let` functionality. Like `core/if-let` but supports multiple
bindings, and unconditional bindings with `:let`:

(if-let [x       (rand-nth [:x1 :x2 false nil    ])  ; Bind truthy x, or -> `else`
         :let [y (rand-nth [:y1 :y2 false nil x  ])] ; Bind any    y
         z       (rand-nth [:z1 :z2 false nil x y])  ; Bind truthy z, or -> `else`
         ]
  [:then-clause x y z]
  [:else-clause])

if-not

macro

clj

cljs

(if-not test-or-bindings then)(if-not test-or-bindings then else)
Supersets `core/if-not` functionality.
Same as `encore/if-let` with `then` `and `else` forms swapped.

if-some

macro

clj

cljs

(if-some bindings then)(if-some bindings then else)
Supersets `core/if-some` functionality. Like `core/if-some` but supports multiple
bindings, and unconditional bindings with `:let`:

(if-some [x       (rand-nth [:x1 :x2 false nil    ])  ; Bind non-nil x, or -> `else`
          :let [y (rand-nth [:y1 :y2 false nil x  ])] ; Bind any     y
          z       (rand-nth [:z1 :z2 false nil x y])  ; Bind non-nil z, or -> `else`
          ]
  [:then-clause x y z]
  [:else-clause])

indexed?

clj

cljs

(indexed? x)

inst->udt

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(inst->udt inst)
Returns given `js/Date` as milliseconds since Unix epoch.

inst?

clj

cljs

(inst? x)
Returns true iff given platform instant (`java.time.Instant` or `js/Date`).

instance!

macro

clj

cljs

added in Encore v3.51.0 (2023-03-13)

(instance! class arg)(instance! class arg {:keys [msg context param ...]})(instance! class arg & {:keys [msg context param ...]})
If (instance? class arg) is true, returns arg.
Otherwise throws runtime `ExceptionInfo` with `unexpected-arg!`.
See `unexpected-arg!` for more info.

int?

clj

cljs

(int? x)
Returns true iff given a number (of standard type) that is:
a fixed-precision integer.

interleave-all

clj

cljs

(interleave-all)(interleave-all c1)(interleave-all c1 c2)(interleave-all c1 c2 & colls)
Like `interleave` but includes all items (i.e. stops when the longest
rather than shortest coll has been consumed).

into!

clj

cljs

(into! to!)(into! to! from)(into! to! xform from)
Like `core/into` but assumes `to!` is a transient, and doesn't call
`persist!` when done. Useful as a performance optimization in some cases.

into-all

clj

cljs

(into-all to from)(into-all to from & more)
Like `into` but supports multiple "from"s.

into-str

clj

cljs

(into-str & xs)
Simple Hiccup-like string templating to complement Tempura.

invert-map

clj

cljs

(invert-map m)
Returns given ?map with keys and vals inverted, dropping non-unique vals!

is!

clj

cljs

(is! x)(is! pred x)(is! pred x data)
Lightweight `have!` that provides less diagnostic info.

ITimeoutFuture

protocol

clj

cljs

members

tf-cancel!

(tf-cancel! _)
Returns true iff the timeout was successfully cancelled (i.e. was previously pending).

tf-poll

(tf-poll _)
Returns :timeout/pending, :timeout/cancelled, or the timeout's completed result.

tf-done?

(tf-done? _)
Returns true iff the timeout is not pending (i.e. has a completed result or is cancelled).

tf-state

(tf-state _)
Returns a map of timeout's public state.

tf-pending?

(tf-pending? _)
Returns true iff the timeout is pending.

tf-cancelled?

(tf-cancelled? _)
Returns true iff the timeout is cancelled.

ITimeoutImpl

protocol

clj

cljs

members

-schedule-timeout

(-schedule-timeout _ msecs f)

keep-callsite

macro

clj

cljs

added in Encore v3.61.0 (2023-07-07)

(keep-callsite & body)
The long-standing CLJ-865 unfortunately means that it's currently
not possible for an inner macro to access the &form metadata of an
outer macro.

This means that inner macros lose callsite information like the
line number of the outer macro.

This util offers a workaround for macro authors:

  (defmacro inner  [] (meta &form))
  (defmacro outer1 []                `(inner))
  (defmacro outer2 [] (keep-callsite `(inner)))

  (inner)  => {:line _, :column _}
  (outer1) => nil
  (outer2) => {:line _, :column _}

keys-by

clj

cljs

(keys-by f coll)
Returns {(f x) x} ?map for xs in `coll`.

ks-nnil?

clj

cljs

(ks-nnil? ks m)

ks<=

clj

cljs

(ks<= ks m)

ks=

clj

cljs

(ks= ks m)

ks>=

clj

cljs

(ks>= ks m)

lazy-seq?

clj

cljs

(lazy-seq? x)

LightAtom

cljs

LimitEntry

cljs

LimitHits

cljs

LimitSpec

cljs

log

cljs

logf

cljs

(logf fmt & xs)

logp

cljs

(logp & xs)

map-entry

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(map-entry k v)
Returns a `MapEntry` with given key and value.

map-keys

clj

cljs

(map-keys key-fn m)
Returns given ?map with (key-fn <key>) keys.

map-vals

clj

cljs

(map-vals val-fn m)
Returns given ?map with (val-fn <val>) vals.

mapply

clj

cljs

(mapply f & args)
Like `apply` but calls `seq-kvs` on final arg.

matching-error

clj

cljs

added in Encore v3.70.0 (2023-10-17)

(matching-error err)(matching-error kind err)(matching-error kind pattern err)
Given a platform error and criteria, returns the error if it matches
all criteria. Otherwise returns nil.

`kind` may be:
  - A predicate function, (fn match? [x]) -> bool
  - A class (e.g. `ArithmeticException`, `AssertionError`, etc.)
  - `:all`     => any    platform error (Throwable or js/Error, etc.)
  - `:common`  => common platform error (Exception or js/Error)
  - `:ex-info` => an `IExceptionInfo` as created by `ex-info`
  - A set of `kind`s as above, at least one of which must match

`pattern` may be:
  - A string or Regex against which `ex-message` must match
  - A map             against which `ex-data`    must match using `submap?`
  - A set of `pattern`s as above, at least one of which must match

When an error with (nested) causes doesn't match, a match will be attempted
against its (nested) causes.

Low-level util, see also `throws`, `throws?`.

max*

macro

clj

cljs

(max* n1 n2)

max-long

clj

cljs

memoize

clj

cljs

(memoize f)(memoize ttl-ms f)(memoize size ttl-ms f)
Alternative way to call `cache`, provided mostly for back compatibility.
See `cache` docstring for details.

memoize-last

clj

cljs

(memoize-last f)
Like `core/memoize` but only caches the given fn's last input.
Great for ReactJS render fn caching, etc.

merge

clj

cljs

(merge & maps)
Like `core/merge` but faster, supports `:merge/dissoc` rvals.

merge-keywords

clj

cljs

(merge-keywords ks)(merge-keywords ks omit-slash?)

merge-meta

clj

cljs

(merge-meta x m)

merge-url-with-query-string

clj

cljs

(merge-url-with-query-string url m)

merge-with

clj

cljs

(merge-with f & maps)
Like `core/merge-with` but faster, supports `:merge/dissoc` rvals.

min*

macro

clj

cljs

(min* n1 n2)

min-long

clj

cljs

ms

clj

cljs

(ms {:keys [years months weeks days hours mins secs msecs ms]})(ms k1 v1)(ms k1 v1 k2 v2)(ms k1 v1 k2 v2 & more)
Returns ~number of milliseconds in period defined by given args.

ms->secs

clj

cljs

(ms->secs ms)

msecs

macro

clj

cljs

(msecs opts)(msecs & {:as opts, :keys [years months weeks days hours mins secs msecs ms]})
Macro version of `ms`.

name-filter

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(name-filter spec)
Given filter `spec`, returns a compiled (fn conform? [name]) that takes
a namespace or any nameable type (string, keyword, symbol).

Spec may be:
  - A namespace. Will conform on exact match.
  - A str/kw/sym, in which "*"s act as wildcards. Will conform on match.
  - A regex pattern. Will conform on match.

  - A vector or set of regex patterns or strs/kws/syms.
    Will conform on ANY match.
    If you need literal "*"s, use #"\*" regex instead.

  - {:allow <spec> :deny <spec>} with specs as above.
    Will conform iff `allow` spec matches AND `deny` spec does NOT.

Resulting conform fn is useful as allowlist and/or denylist.
Example inputs: namespace strings, class names, ids, etc.

Spec examples:
  *ns*, #{}, "*", "foo.bar", "foo.bar.*", #{"foo" "bar.*"},
  {:allow #{"foo" "bar.*"} :deny #{"foo.*.bar.*"}},
  #"(foo1|foo2)\.bar".

name-with-attrs

clj

cljs

(name-with-attrs sym args)(name-with-attrs sym args attrs-merge)
Given a symbol and args, returns [<name-with-attrs-meta> <args> <attrs>]
with support for `defn` style `?docstring` and `?attrs-map`.

nameable?

clj

cljs

(nameable? x)

named?

clj

cljs

(named? x)

nanoid

clj

cljs

(nanoid)(nanoid len)
Returns a random "Nano ID" of given length, Ref. <https://github.com/ai/nanoid>.
Uses strong randomness when possible. See also `uuid-str`, `rand-id-fn`.

nat-float?

clj

cljs

(nat-float? x)

nat-int?

clj

cljs

(nat-int? x)

nat-num?

clj

cljs

(nat-num? x)

nblank-str?

clj

cljs

(nblank-str? x)

nblank?

clj

cljs

(nblank? x)

neg-float?

clj

cljs

(neg-float? x)

neg-int?

clj

cljs

(neg-int? x)

neg-num?

clj

cljs

(neg-num? x)

nempty-str?

clj

cljs

(nempty-str? x)

nested-merge

clj

cljs

(nested-merge & maps)
Like `merge` but does nested merging.

nested-merge-with

clj

cljs

(nested-merge-with f & maps)
Like `merge-with` but does nested merging.

new-object

macro

clj

cljs

(new-object)

newline

clj

cljs

added in Encore v3.68.0 (2023-09-25)

Single system newline

newlines

clj

cljs

added in Encore v3.68.0 (2023-09-25)

Double system newline

nneg?

clj

cljs

(nneg? x)

nnil

clj

cljs

(nnil)(nnil x)(nnil x y)(nnil x y z)(nnil x y z & more)
Returns first non-nil arg, or nil.

node-paths

clj

cljs

(node-paths m)(node-paths node-pred m)(node-paths node-pred m basis)

node-target?

cljs

norm-word-breaks

clj

cljs

(norm-word-breaks s)
Converts all word breaks of any form and length (including line breaks of any
form, tabs, spaces, etc.) to a single regular space.

now-inst

clj

cljs

added in Encore v3.66.0 (2023-08-23)

(now-inst)
Returns current system instant as `js/Date`.

now-nano

clj

cljs

Returns current value of best-resolution time source as nanoseconds.

now-udt

clj

cljs

(now-udt)
Returns current system insant as milliseconds since Unix epoch.

nzero-num?

clj

cljs

(nzero-num? x)

oget

cljs

(oget k)(oget o k)(oget o k not-found)
Like `get` for JS objects.

oget-in

cljs

(oget-in ks)(oget-in o ks)(oget-in o ks not-found)
Like `get-in` for JS objects.

or-some

macro

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(or-some)(or-some x)(or-some x & next)
Like `or`, but returns the first non-nil form (may be falsey).

oset

cljs

(oset o k v)
Like `assoc` for JS objects.

oset-in

cljs

(oset-in o ks v)
Experimental, subject to change without notice.
Like `assoc-in` for JS objects.

parse-js-int

cljs

(parse-js-int s)

parse-query-params

clj

cljs

(parse-query-params s & [keywordize? encoding])
Based on `ring-codec/form-decode`.

parse-version

clj

cljs

(parse-version x)

path

clj

cljs

(path & parts)

perc

clj

cljs

(perc n divisor)

pnum-complement

clj

cljs

(pnum-complement pnum)

pnum?

clj

cljs

(pnum? x)
Returns true iff given number in unsigned unit proportion interval ∈ℝ[0,1].

pos-float?

clj

cljs

(pos-float? x)

pos-int?

clj

cljs

(pos-int? x)

pos-num?

clj

cljs

(pos-num? x)

pow

clj

cljs

(pow n exp)

pr

clj

cljs

added in Encore v3.98.0 (2024-04-08)

Identical to `core/pr`.

pr-edn

clj

cljs

(pr-edn x)
Prints given arg to an edn string readable with `read-edn`.

pr-json

cljs

added in Encore v3.98.0 (2024-04-08)

(pr-json x)
Returns given Cljs argument as JSON string.

Pred

cljs

pred

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(pred pred-fn)
Experimental, subject to change without notice.
Wraps given predicate fn to return `Pred` for use with `submap?`, etc.
Arity of predicate fn depends on context in which it'll be used.
See also `pred-fn`.

pred-fn

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(pred-fn pred)
Experimental, subject to change without notice.
Returns unwrapped predicate fn when given `Pred`, otherwise returns nil.
See also `pred`.

preserve-reduced

clj

cljs

(preserve-reduced rf)
Public version of `core/preserving-reduced`.

print

clj

cljs

added in Encore v3.98.0 (2024-04-08)

Identical to `core/print`.

println

clj

cljs

added in Encore v3.98.0 (2024-04-08)

Identical to `core/println`.

prn

clj

cljs

added in Encore v3.98.0 (2024-04-08)

Identical to `core/prn`.

pull-val!

clj

cljs

(pull-val! atom_ k)(pull-val! atom_ k not-found)
Removes and returns value mapped to key:
(let [a (atom {:k :v})]
  [(pull-val! a :k) @a]) => [:v {}]

qb

macro

clj

cljs

(qb spec form & more)(qb spec form)
Simple util to benchmark/compare runtime of given form/s.

Runs sets of laps for each given form, recording the total runtime of each set.
Returns the the total runtime in msecs of the fastest set of laps for each form.

  (quick-bench [<num-sets> <num-laps>] <form1> <form2> <...>) =>
    [<total runtime msecs of fastest set of laps for form1>
     <total runtime msecs of fastest set of laps for form2>
     <...>]

   Total number of runs for each form is: `num-sets` * `num-laps`

If omitted, the default `num-sets` is 6 (to include warmup):
  (quick-bench <num-laps> <form1> <form2> <...>)

Example (comparing runtime of `first` and `nth` against vector):
  (let [v [:a]] (quick-bench 1e6 (first v) (nth v 0))) => [67.43 39.05]

qualified-ident?

clj

cljs

(qualified-ident? x)

qualified-keyword?

clj

cljs

(qualified-keyword? x)

qualified-symbol?

clj

cljs

(qualified-symbol? x)

queue

clj

cljs

(queue coll)(queue)
Returns a new `PersistentQueue`.

queue*

clj

cljs

(queue* & items)
Returns a new `PersistentQueue` given items.

queue?

clj

cljs

(queue? x)
Returns true iff given a `PersistentQueue`.

quick-bench

macro

clj

cljs

(quick-bench spec form & more)(quick-bench spec form)
Simple util to benchmark/compare runtime of given form/s.

Runs sets of laps for each given form, recording the total runtime of each set.
Returns the the total runtime in msecs of the fastest set of laps for each form.

  (quick-bench [<num-sets> <num-laps>] <form1> <form2> <...>) =>
    [<total runtime msecs of fastest set of laps for form1>
     <total runtime msecs of fastest set of laps for form2>
     <...>]

   Total number of runs for each form is: `num-sets` * `num-laps`

If omitted, the default `num-sets` is 6 (to include warmup):
  (quick-bench <num-laps> <form1> <form2> <...>)

Example (comparing runtime of `first` and `nth` against vector):
  (let [v [:a]] (quick-bench 1e6 (first v) (nth v 0))) => [67.43 39.05]

rand-id-fn

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(rand-id-fn {:keys [chars len rand-bytes-fn], :or {chars :nanoid, len 21, rand-bytes-fn secure-rand-bytes}})
Returns a (fn rand-id []) that returns random id strings.
Uses strong randomness when possible.

Options include:
  `:chars`         - ∈ #{<string> :nanoid :alphanumeric :no-look-alikes ...}
  `:len`           - Length of id strings to generate
  `:rand-bytes-fn` - Optional (fn [size]) to return random byte array of given size

See also `uuid-str`, `nano-id`.

rate-limiter

clj

cljs

(rate-limiter spec)(rate-limiter opts spec)
Takes a spec of form
  [           [<n-max-reqs> <msecs-window>] ...] or
  {<limit-id> [<n-max-reqs> <msecs-window>]},
and returns a basic stateful (fn a-rate-limiter [req-id] [command req-id]).

Call the limiter fn with a request id (e.g. username) by which to count/limit.
Will return:
  - nil when allowed (all limits pass for given req-id), or
  - [<worst-limit-id> <worst-backoff-msecs> {<limit-id> <backoff-msecs>}]
    when denied (any limits fail for given req-id).

Or call the limiter fn with an additional command argument:
  `:rl/peek`  <req-id> - Check limits w/o incrementing count.
  `:rl/reset` <req-id> - Reset all limits for given req-id.

Example:

  (defonce my-rate-limiter
    (rate-limiter
      {"1  per sec" [1   1000]
       "10 per min" [10 60000]}))

  (defn send-message! [username msg-content]
    (if-let [fail (my-rate-limiter username)]
      (throw (ex-info "Sorry, rate limited!" {:fail fail}))
      <send message>))

rcompare

clj

cljs

(rcompare x y)
Reverse comparator.

re-pattern?

clj

cljs

(re-pattern? x)

read-edn

clj

cljs

(read-edn s)(read-edn opts s)
Reads given edn string to return a Clj/s value.

read-json

cljs

added in Encore v3.98.0 (2024-04-08)

(read-json s)(read-json kw-keys? s)
Reads given JSON string to return a Cljs value.

reassoc-some

clj

cljs

(reassoc-some m k v)(reassoc-some m m-kvs)(reassoc-some m k v & kvs)
Assocs each kv to given ?map if its value is nil, otherwise dissocs it.

reduce-indexed

clj

cljs

(reduce-indexed rf init coll)
Like `reduce` but takes (rf [acc idx in]) with idx as in `map-indexed`.
As `reduce-kv` against vector coll, but works on any seqable coll type.

reduce-interleave-all

clj

cljs

added in Encore v3.66.0 (2023-08-23)

(reduce-interleave-all rf init colls)
Reduces sequence of elements interleaved from given `colls`.
(reduce-interleave-all conj [] [[:a :b] [1 2 3]]) => [:a 1 :b 2 3]

reduce-kvs

clj

cljs

(reduce-kvs rf init kvs)
Like `reduce-kv` but takes a flat sequence of kv pairs.

reduce-multi

clj

cljs

added in Encore v3.66.0 (2023-08-23)

(reduce-multi rf init coll)(reduce-multi rf1 init1 rf2 init2 coll)(reduce-multi rf1 init1 rf2 init2 rf3 init3 coll)
Like `reduce` but supports separate simultaneous accumulators
as a micro-optimization when reducing a large collection multiple
times.

reduce-n

clj

cljs

(reduce-n rf init end)(reduce-n rf init start end)(reduce-n rf init start end step)

reduce-obj

cljs

(reduce-obj f init o)
Like `reduce-kv` but for JavaScript objects.

reduce-top

clj

cljs

(reduce-top n rf init coll)(reduce-top n keyfn rf init coll)(reduce-top n keyfn cmp rf init coll)
Reduces the top `n` items from `coll` of N items.
Clj impln is O(N.logn) vs O(N.logN) for (take n (sort-by ...)).

reduce-zip

clj

cljs

added in Encore v3.33.0 (2022-11-15)

(reduce-zip rf init xs ys)(reduce-zip rf init xs ys not-found)
Reduces given sequential xs and ys as pairs (e.g. key-val pairs).
Calls (rf acc x y) for each sequential pair.

Useful, among other things, as a more flexible version of `zipmap`.

remove-keys

clj

cljs

(remove-keys key-pred m)
Returns given ?map, removing keys for which (key-pred <key>) is truthy.

remove-vals

clj

cljs

(remove-vals val-pred m)
Returns given ?map, removing keys for which (val-pred <val>) is truthy.

rename-keys

clj

cljs

(rename-keys replacements m)
Returns a map like the one given, replacing keys using
given {<old-new> <new-key>} replacements. O(min(n_replacements, n_m)).

repeatedly-into

clj

cljs

(repeatedly-into coll n f)
Like `repeatedly` but faster and `conj`s items into given collection.

require-telemere-if-present

macro

clj

cljs

added in Encore v3.68.0 (2023-09-25)

(require-telemere-if-present)
Experimental, subject to change without notice!
Requires Telemere if it's present, otherwise no-ops.
For Cljs: needs ClojureScript >= v1.9.293, and must be placed at top of file.
Used in cooperation with `signal!`.

reset!?

clj

cljs

(reset!? atom_ val)
Atomically swaps value of `atom_` to `val` and returns
true iff the atom's value changed. See also `reset-in!?`.

reset-in!

clj

cljs

(reset-in! atom_ val)(reset-in! atom_ ks val)(reset-in! atom_ ks not-found val)
Like `reset!` but supports `update-in` semantics, returns <old-key-val>.

reset-in!?

clj

cljs

(reset-in!? atom_ val)(reset-in!? atom_ ks val)(reset-in!? atom_ ks not-found val)
Like `reset-in!` but returns true iff the atom's value changed.

reset-val!

clj

cljs

(reset-val! atom_ k val)(reset-val! atom_ k not-found val)
Like `reset-in!` but optimized for single-key case.

reset-val!?

clj

cljs

(reset-val!? atom_ k new-val)
Like `reset-in!?` but optimized for single-key case.

revery-kv?

clj

cljs

(revery-kv? pred coll)

revery?

clj

cljs

(revery? pred coll)(revery? xform pred coll)

rfirst

clj

cljs

(rfirst pred coll)(rfirst xform pred coll)

rfirst-kv

clj

cljs

(rfirst-kv pred coll)

rnum?

clj

cljs

(rnum? x)
Returns true iff given number in signed unit proportion interval ∈ℝ[-1,1].

rolling-counter

clj

cljs

(rolling-counter msecs)
Experimental, subject to change without notice.
Returns a RollingCounter that you can:
  - Invoke to increment count in last `msecs` window and return RollingCounter.
  - Deref  to return    count in last `msecs` window.

rolling-vector

clj

cljs

added in Encore v3.45.0 (2022-12-13)

(rolling-vector nmax)(rolling-vector nmax {:keys [gc-every init-val], :or {gc-every 16000.0}})
Returns a stateful fn of 2 arities:
  [ ] => Returns current sub/vector in O(1).
  [x] => Adds `x` to right of sub/vector, maintaining length <= `nmax`.
         Returns current sub/vector.

Useful for maintaining limited-length histories, etc.
See also `rolling-list` (Clj only).

RollingCounter

cljs

round*

clj

cljs

(round* n)(round* kind n)(round* kind precision n)

round0

clj

cljs

(round0 n)

round1

clj

cljs

(round1 n)

round2

clj

cljs

(round2 n)

roundn

clj

cljs

(roundn precision n)

rsome

clj

cljs

(rsome pred coll)(rsome xform pred coll)

rsome-kv

clj

cljs

(rsome-kv pred coll)

run!

clj

cljs

(run! proc coll)

run-kv!

clj

cljs

(run-kv! proc m)

run-kvs!

clj

cljs

(run-kvs! proc kvs)

run-obj!

cljs

(run-obj! proc obj)

satisfies!

macro

clj

cljs

added in Encore v3.51.0 (2023-03-13)

(satisfies! protocol arg)(satisfies! protocol arg {:keys [msg context param ...]})(satisfies! protocol arg & {:keys [msg context param ...]})
If (satisfies? protocol arg) is true, returns arg.
Otherwise throws runtime `ExceptionInfo` with `unexpected-arg!`.
See `unexpected-arg!` for more info.

satisfies?

macro

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(satisfies? protocol x)
Faster `satisfies?` to work around CLJ-1814 until a proper upstream fix.
May cache, so possibly inappropriate for dynamic work.

sayf

cljs

(sayf fmt & xs)

sayp

cljs

(sayp & xs)

sb-append

clj

cljs

(sb-append str-builder x)(sb-append str-builder x & more)
Appends given string/s to given string builder. See also `str-builder.`

sb-length

clj

cljs

added in Encore v3.107.0 (2024-05-05)

(sb-length sb)
Returns given string builder's current length (character count).

secs

clj

cljs

(secs opts)(secs k1 v1)(secs k1 v1 k2 v2)(secs k1 v1 k2 v2 & more)
Returns ~number of seconds in period defined by given args.

secs->ms

clj

cljs

(secs->ms secs)

secure-rand-bytes

clj

cljs

(secure-rand-bytes size)
Returns a random byte array of given size. Uses strong randomness when possible.

select-nested-keys

clj

cljs

added in Encore v3.34.0 (2022-11-16)

(select-nested-keys src-map key-spec)
Like `select-keys` but supports nested key spec:

  (select-nested-keys
    {:a :A :b :B :c {:c1 :C1 :c2 :C2} :d :D} ; `src-map`
    [:a {:c [:c1], :d [:d1 :d2]}]) ; `key-spec`

    => {:a :A, :c {:c1 :C1}, :d :D}

Note that as with the `{:d [:d1 :d2]}` spec in the example above,
if spec expects a nested map but the actual value is not a map,
the actual value will be included in output as-is.

Has the same behaviour as `select-keys` when `key-spec` is a
simple vector of keys.

seq-kvs

clj

cljs

(seq-kvs {:a :A}) => (:a :A).

set-var-root!

macro

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(set-var-root! var-sym root-val)
Sets root binding (value) of the var identified by given symbol, and returns
the new value. Cross-platform. See also `update-var-root!`.

signal!

macro

clj

cljs

added in Encore v3.68.0 (2023-09-25)

(signal! {:as opts, :keys [fallback elidable? location inst uid middleware sample-rate kind ns id level when rate-limit ctx parent trace? do let data msg error run & kvs]})
Experimental, subject to change without notice!
Expands to `taoensso.telemere/signal!` call if Telemere is present,
otherwise expands to `fallback` form.

MUST be used with `require-telemere-if-present`:

  (ns my-ns (:require [taoensso.encore :as enc]))
  (encore/require-telemere-if-present) ; At top of file, just below `ns` form

  (encore/signal! {<signal-opts> :fallback (println "Prints iff Telemere not present")})

For more info, see:
  - Telemere `signal!`, Ref. <https://www.taoensso.com/telemere/signal!>
  - Telemere API,       Ref. <https://www.taoensso.com/telemere/api>
  - Telemere Wiki docs, Ref. <https://www.taoensso.com/telemere/wiki>

simple-ident?

clj

cljs

(simple-ident? x)

simple-keyword?

clj

cljs

(simple-keyword? x)

simple-symbol?

clj

cljs

(simple-symbol? x)

SimpleCacheEntry

cljs

some=

clj

cljs

(some= x y)(some= x y & more)

some?

clj

cljs

(some? x)
Same as `core/some?` (added in Clojure v1.6).

sortv

clj

cljs

(sortv coll)(sortv comparator coll)(sortv ?keyfn comparator coll)
Like `core/sort` but:
- Returns a vector.
- `comparator` can be `:asc`, `:desc`, or an arbitrary comparator.
- An optional `keyfn` may be provided, as in `core/sort-by`.

str-?index

clj

cljs

(str-?index s substr)(str-?index s substr start-idx)(str-?index s substr start-idx last?)
Returns (first/last) ?index of substring if it exists within given string.

str-builder

clj

cljs

(str-builder)(str-builder init)
Returns a new stateful string builder:
  - `java.lang.StringBuilder`  for Clj
  - `goog.string.StringBuffer` for Cljs

See also `sb-append`.

str-builder?

clj

cljs

(str-builder? x)

str-contains?

clj

cljs

(str-contains? s substr)

str-ends-with?

clj

cljs

(str-ends-with? s substr)

str-join

clj

cljs

(str-join xs)(str-join separator xs)(str-join separator xform xs)
Faster generalization of `clojure.string/join` with transducer support.

str-join-once

clj

cljs

(str-join-once separator coll)
Like `string/join` but skips nils and duplicate separators.

str-replace

clj

cljs

(str-replace s match replacement)
Like `str/replace` but provides consistent clj/s behaviour.

Workaround for <http://dev.clojure.org/jira/browse/CLJS-794>,
               <http://dev.clojure.org/jira/browse/CLJS-911>.

Note that ClojureScript 1.7.145 introduced a partial fix for CLJS-911.
A full fix could unfortunately not be introduced w/o breaking compatibility
with the previously incorrect behaviour. CLJS-794 also remains unresolved.

str-rf

clj

cljs

(str-rf)(str-rf acc)(str-rf acc in)
String builder reducing fn.

str-starts-with?

clj

cljs

(str-starts-with? s substr)

stringy?

clj

cljs

(stringy? x)

submap?

clj

cljs

(submap? m sub)
Returns true iff `sub` is a (possibly nested) submap of `m`,
i.e. iff every (nested) value in `sub` has the same (nested) value in `m`.
Uses stack recursion so supports only limited nesting.

submaps?

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(submaps? maps subs)
Experimental, subject to change without notice.
Returns true iff `sub_i` is a (possibly nested) submap of `m_i`.
Uses `submap?`.

swap-in!

clj

cljs

(swap-in! atom_ f)(swap-in! atom_ ks f)(swap-in! atom_ ks not-found f)
Like `swap!` but supports `update-in` semantics and `swapped`.
Returns <new-key-val> or <swapped-return-val>:
  (swap-in! (atom {:k1 {:k2 5}}) [:k1 :k2] inc) => 6
  (swap-in! (atom {:k1 {:k2 5}}) [:k1 :k2]
    (fn [old] (swapped (inc old) old))) => 5

swap-val!

clj

cljs

(swap-val! atom_ k f)(swap-val! atom_ k not-found f)
Like `swap-in!` but optimized for single-key case:
(swap-val! (atom {:k 5}) :k inc) => 6
(swap-val! (atom {:k 5}) :k
  (fn [old] (swapped (inc old) old))) => 5

Swapped

cljs

swapped

clj

cljs

(swapped new-val return-val)
For use within the swap functions of `swap-in!` and `swap-val!`.

Allows the easy decoupling of new and returned values. Compare:
  (let [a (atom 0)] [(core/swap! a (fn [old]          (inc old)     )) @a]) [1 1] ; new=1, return=1
  (let [a (atom 0)] [(swap-in!   a (fn [old] (swapped (inc old) old))) @a]) [0 1] ; new=1, return=0

Faster and much more flexible than `core/swap-vals!`, etc.
Especially useful when combined with the `update-in` semantics of `swap-in!`, etc.

swapped?

clj

cljs

(swapped? x)
Returns true iff given `Swapped` argument.

takev

clj

cljs

(takev n coll)

test-fixtures

clj

cljs

added in Encore v3.31.0 (2022-10-27)

(test-fixtures fixtures-map)
Given a {:before ?(fn []) :after ?(fn [])} map, returns cross-platform
test fixtures for use by both `clojure.test` and `cljs.test`:

  (let [f (test-fixtures {:before (fn [] (test-setup))})]
    (clojure.test/use-fixtures :once f)
       (cljs.test/use-fixtures :once f))

thread-local

macro

clj

cljs

added in Encore v3.48.0 (2023-01-25)

(thread-local & body)
Given a body that returns an initial value for the current thread,
returns a `ThreadLocal` proxy that can be derefed to get the current
thread's current value.

Commonly used to achieve thread safety during Java interop.
In the common case, `body` will be a call to some Java constructor
that returns a non-thread-safe instance.

Example:
  (def thread-local-simple-date-format_
    "Deref to return a thread-local `SimpleDateFormat`"
    (thread-local (SimpleDateFormat. "yyyy-MM-dd")))

  (.format @thread-local-simple-date-format_ (Date.)) => "2023-01-24"

NB: don't pass the derefed value to other threads!

thread-local-proxy

macro

clj

cljs

(thread-local-proxy & body)
Low-level, see `thread-local` instead.

throws

macro

clj

cljs

added in Encore v3.31.0 (2022-10-27)

(throws form)(throws kind form)(throws kind pattern form)
Evals `form` and if it throws an error that matches given criteria using
`matching-error`, returns the matching error. Otherwise returns nil.

See also `matching-error`, `throws?`.

throws?

macro

clj

cljs

added in Encore v3.31.0 (2022-10-27)

(throws? form)(throws? kind form)(throws? kind pattern form)
Evals `form` and if it throws an error that matches given criteria using
`matching-error`, returns true. Otherwise returns false.

Useful for unit tests, e.g.:
  (is (throws? {:a :b} (throw (ex-info "Test" {:a :b :c :d}))))

See also `matching-error`, `throws`.

TickedCacheEntry

cljs

time-ms

macro

clj

cljs

(time-ms & body)
Returns number of milliseconds it took to execute body.

time-ns

macro

clj

cljs

(time-ns & body)
Returns number of nanoseconds it took to execute body.

timeout-future?

clj

cljs

(timeout-future? x)

TimeoutFuture

cljs

top

clj

cljs

(top n coll)(top n keyfn coll)(top n keyfn cmp coll)
Returns a sorted vector of the top `n` items from `coll` using `reduce-top`.

top-into

clj

cljs

(top-into to n coll)(top-into to n keyfn coll)(top-into to n keyfn cmp coll)
Conjoins the top `n` items from `coll` into `to` using `reduce-top`.

transient?

clj

cljs

(transient? x)

try*

macro

clj

cljs

added in Encore v3.67.0 (2023-09-08)

(try* expr* catch-clauses* ?finally-clause)
Like `try`, but `catch` clause class may be:
  `:ex-info`          - Catches only `ExceptionInfo`
  `:common`           - Catches `js/Error` (Cljs), `Exception` (Clj)
  `:all`              - Catches `:default` (Cljs), `Throwable` (Clj)
  `:all-but-critical` - Catches `:default` (Cljs), `Exception` and `AssertionError` (Clj)

Addresses CLJ-1293 and the fact that `AssertionError`s are typically NON-critical
(so desirable to catch, in contrast to other `Error` classes).

try-eval

macro

clj

cljs

added in Encore v3.50.0 (2023-03-07)

(try-eval form)
If `form` can be successfully evaluated at macro-expansion time, expands to `form`.
Otherwise expands to `nil`.

udt->inst

clj

cljs

added in Encore v3.98.0 (2024-04-08)

(udt->inst msecs-since-epoch)
Returns given milliseconds since Unix epoch as `js/Date`.

udt?

clj

cljs

(udt? x)

unexpected-arg!

clj

cljs

added in Encore v3.51.0 (2023-03-13)

(unexpected-arg! arg)(unexpected-arg! arg opts)(unexpected-arg! arg k1 v1)(unexpected-arg! arg k1 v1 k2 v2)(unexpected-arg! arg k1 v1 k2 v2 k3 v3)(unexpected-arg! arg k1 v1 k2 v2 k3 v3 k4 v4)
Throws runtime `ExceptionInfo` to indicate an unexpected argument.
Takes optional kvs for merging into exception's data map.

  (let [mode :unexpected]
    (case mode
      :read  (do <...>)
      :write (do <...>)
      (unexpected-arg! mode
        {:context  `my-function
         :param    'mode
         :expected #{:read :write}}))) =>

  Unexpected argument: :unexpected
  {:arg {:value :unexpected, :type clojure.lang.Keyword},
   :context 'taoensso.encore/my-function
   :param 'mode
   :expected #{:read :write}}

See also `bad-arg!`.

update-in

clj

cljs

(update-in m ks f)(update-in m ks not-found f)
Like `core/update-in` but:.
- Empty ks will return (f m), not act like [nil] ks.
- Adds support for `not-found`.
- Adds support for special return vals: `:update/dissoc`, `:update/abort`.

update-var-root!

macro

clj

cljs

added in Encore v3.68.0 (2023-09-25)

(update-var-root! var-sym update-fn)
Updates root binding (value) of the var identified by given symbol, and returns
the new value:
  (update-var-root! my-var (fn [old-root-val] <new-root-val>)) => <new-root-val>

Similar to `alter-var-root` but cross-platform and takes a symbol rather than a var.
See also `set-var-root!`.

url-decode

clj

cljs

(url-decode s & [encoding])
Stolen from <http://goo.gl/99NSR1>.

url-encode

clj

cljs

(url-encode s)

uuid

clj

cljs

added in Encore v3.75.0 (2024-01-29)

(uuid)
For Clj: returns a random `java.util.UUID`.
For Cljs: returns a random UUID string.

Uses strong randomness when possible.
See also `uuid-str`, `nanoid`, `rand-id-fn`.

uuid-str

clj

cljs

(uuid-str max-len)(uuid-str)
Returns a random UUID string of given length (max 36).
Uses strong randomness when possible. See also `uuid`, `nanoid`, `rand-id-fn`.

vec2?

clj

cljs

(vec2? x)

vec3?

clj

cljs

(vec3? x)

vinterleave-all

clj

cljs

added in Encore v3.66.0 (2023-08-23) for !=2 arities

(vinterleave-all colls)(vinterleave-all c1 c2)(vinterleave-all c1 c2 c3)(vinterleave-all c1 c2 c3 & colls)
Like `interleave`, but:
  - Returns a vector rather than lazy seq (=> greedy).
  - Includes all items (i.e. stops when the longest rather than
    shortest coll has been consumed).

Single-arity version takes a coll of colls.

vnext

clj

cljs

(vnext v)

vrest

clj

cljs

(vrest v)

vsplit-first

clj

cljs

(vsplit-first v)

vsplit-last

clj

cljs

(vsplit-last v)

when

macro

clj

cljs

(when test-or-bindings & body)
Supersets `core/when` and `core/when-let` functionality. When `test-or-bindings` is
a vector, same as `encore/when-let`. Otherwise same as `core/when`.

when-let

macro

clj

cljs

(when-let bindings & body)
Supersets `core/when-let` functionality. Like `core/when-let` but supports multiple
bindings, and unconditional bindings with `:let`:

(when-let [x       (rand-nth [:x1 :x2 false nil    ])  ; Bind truthy x, or -> nil
           :let [y (rand-nth [:y1 :y2 false nil x  ])] ; Bind any    y
           z       (rand-nth [:z1 :z2 false nil x y])  ; Bind truthy z, or -> nil
           ]
  [:body x y z])

when-not

macro

clj

cljs

(when-not test-or-bindings & body)
Supersets `core/when-not` functionality.
Same as `encore/if-let` with `body` as `else` form.

when-some

macro

clj

cljs

(when-some test-or-bindings & body)
Supersets `core/when-some` functionality. Like `core/when-some` but supports multiple
bindings, and unconditional bindings with `:let`:

(when-some [x       (rand-nth [:x1 :x2 false nil    ])  ; Bind non-nil x, or -> `else`
            :let [y (rand-nth [:y1 :y2 false nil x  ])] ; Bind any     y
            z       (rand-nth [:z1 :z2 false nil x y])  ; Bind non-nil z, or -> `else`
            ]
  [:body x y z])

with-truss-data

macro

clj

cljs

(with-truss-data data & body)
Executes body with dynamic assertion data bound to given value.
This data will be included in any violation errors thrown by body.

without-meta

clj

cljs

(without-meta x)

xdistinct

clj

cljs

(xdistinct)(xdistinct keyfn)
Returns a stateful transducer like (core/distinct) that supports an optional
key function. Retains only items with distinct (keyfn <item>).

zero-num?

clj

cljs

(zero-num? x)