Liking cljdoc? Tell your friends :D

desiderata

Lint and test clojars badge cljdoc badge

Things wanted or needed but missing from clojure.core.

This is not just a collection of utility functions, but more significant features (and maybe some utility functions). Maybe it's best to just poke around in the documentation? Otherwise, I've attempted to provide details below.

Baseline versions

  • JVM: 21
  • Clojure: 1.12.0

defrecord

You can use systems.thoughtfull.desiderata/defrecord as a drop-in replacement for clojure.core/defrecord and what you get are four new features. The first (minor) feature is the factory function (i.e. map->...) takes keyword arguments.

Docstring

systems.thoughtfull.desiderata/defrecord takes a docstring that it appends to the end of both the factory and positional factory functions.

user> (require '[systems.thoughtfull.desiderata :as desiderata])
nil

user> (desiderata/defrecord Widget
"A widget for frobbing gizmos.

width and height are in metric."
[width height])
user.Widget

user> (doc map->Widget)
-------------------------
user/map->Widget
([& {:keys [width height]}])
  Factory function for class user.Widget, taking a map of keywords to field values.

  A widget for frobbing gizmos.
  
  width and height are in metric.
nil

user> (doc ->Widget)
-------------------------
user/->Widget
([width height])
  Positional factory function for class user.Widget.

  A widget for frobbing gizmos.
  
  width and height are in metric.
nil

Defaults

You can specify a map of default values for fields (and non-fields) with the systems.thoughtfull.desiderata/defaults option. Values given to the factory or positional factory functions will override defaults.

user> (desiderata/defrecord Gizmo
[name]
::desiderata/defaults
{:name "Gizmo"
 :color :blue})
user.Gizmo

user> (->Gizmo "the Great")
{:name "the Great", :color :blue}

user> (map->Gizmo :texture :bumpy)
{:name "Gizmo", :color :blue, :texture :bumpy}

Initializer

A method with the same name as the defrecord is an initializer method called from both the factory and positional factory functions. The initializer runs after the defaults and arguments have merged and the factory function has executed.

As a sanity check, the initializer must return an instance of the defrecord, otherwise an IllegalStateException is thrown.

user> (desiderata/defrecord Company
[debt equity]
(Company
  [this]
  (assoc this :gearing-ratio (/ debt equity))))
user.Company

user> (->Company 100 1000)
{:debt 100, :equity 1000, :gearing-ratio 1/10}

Thread.UncaughtExceptionHandler

There are two convenience functions for working with Thread.UncaughtExceptionHandler. uncaught-exception-handler will adapt a two argument function to a Thread.UncaughtExceptionHandler.

set-default-uncaught-exception-handler-fn! will set the default Thread.UncaughtExceptionHandler after adapting the given two argument function to a Thread.UncaughtExceptionHandler. The default handler is used if there is no handler defined for a Thread and its ThreadGroup (see Thread/setDefaultUncaughtExceptionHandler).

thread-factory

thread-factory creates a java.util.concurrent.ThreadFactory for use particularly with executors. It mostly passes along options to Threads as it creates them, however, a notable feature is it will set a Thread.UncaughtExceptionHandler on each thread it creates. It adapts the uncaught-exception-handler-fn into a Thread.UncaughtExceptionHandler using uncaught-exception-handler.

Another notable and Clojure-specific feature is the ThreadFactory will convey thread bindings to create threads. You can disable this by passing :convey-bindings? false, but by default it is enabled.

It will also take a name which is used as a prefix to the names of threads it creates.

clj-kondo

To import custom clj-kondo hooks for systems.thoughtfull.desiderata/defrecord use

clj-kondo --lint "$(clojure -Spath)" --copy-configs --skip-lint

License

Copyright © technosophist

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close