Liking cljdoc? Tell your friends :D

hive-dsl.adt

Closed algebraic data types (ADTs) with keyword dispatch.

defadt defines sum types that are:

  • Closed at definition site (variant set is fixed at macro-expansion time)
  • Dispatched via keyword (works with Clojure case)
  • Coercible from keywords (:event/started → variant value)
  • Serializable as plain EDN maps (round-trip safe)
  • Registered in a global type registry

Runtime representation: plain maps with :adt/type and :adt/variant keys. This keeps ADT values printable, serializable, and compatible with all Clojure map operations.

Usage: ;; Data-carrying variants (defadt EventType "Event types for hivemind communication." [:event/started {:task string?}] [:event/progress {:message string?}])

;; Enum variants (no associated data) (defadt SpawnMode "Agent spawn modes." :spawn/vterm :spawn/headless)

;; Mixed (defadt Shape [:shape/circle {:radius number?}] [:shape/rect {:w number? :h number?}] :shape/point)

Generated API: (event-type :event/started {:task "X"}) ; constructor (event-type? x) ; type predicate (->event-type :event/started) ; keyword coercion (adt-case EventType evt ; exhaustive match :event/started (str (:task evt)) :event/progress (str (:message evt)))

Closed algebraic data types (ADTs) with keyword dispatch.

defadt defines sum types that are:
- Closed at definition site (variant set is fixed at macro-expansion time)
- Dispatched via keyword (works with Clojure `case`)
- Coercible from keywords (:event/started → variant value)
- Serializable as plain EDN maps (round-trip safe)
- Registered in a global type registry

Runtime representation: plain maps with :adt/type and :adt/variant keys.
This keeps ADT values printable, serializable, and compatible with all
Clojure map operations.

Usage:
  ;; Data-carrying variants
  (defadt EventType
    "Event types for hivemind communication."
    [:event/started   {:task string?}]
    [:event/progress  {:message string?}])

  ;; Enum variants (no associated data)
  (defadt SpawnMode
    "Agent spawn modes."
    :spawn/vterm
    :spawn/headless)

  ;; Mixed
  (defadt Shape
    [:shape/circle {:radius number?}]
    [:shape/rect   {:w number? :h number?}]
    :shape/point)

Generated API:
  (event-type :event/started {:task "X"})  ; constructor
  (event-type? x)                           ; type predicate
  (->event-type :event/started)             ; keyword coercion
  (adt-case EventType evt                   ; exhaustive match
    :event/started  (str (:task evt))
    :event/progress (str (:message evt)))
raw docstring

adt-caseclj/smacro

(adt-case type-ref expr & clauses)

Exhaustive pattern match on an ADT value's variant keyword.

Checks at macro-expansion time that all variants are covered — compile-time exhaustiveness checking. Uses case under the hood for O(1) dispatch.

type-ref must be a symbol naming a defadt type (e.g. EventType), or a type metadata map. The type's defadt namespace must be required so the type is in the registry at macro-expansion time.

(adt-case EventType evt :event/started (str "task: " (:task evt)) :event/progress (str "msg: " (:message evt)) :event/completed "done")

Compile-time error if:

  • Any variant is missing (non-exhaustive)
  • Any unknown variant is listed (typo detection)
Exhaustive pattern match on an ADT value's variant keyword.

Checks at macro-expansion time that all variants are covered — compile-time
exhaustiveness checking. Uses `case` under the hood for O(1) dispatch.

type-ref must be a symbol naming a defadt type (e.g. EventType), or a type
metadata map. The type's defadt namespace must be required so the type is
in the registry at macro-expansion time.

(adt-case EventType evt
  :event/started   (str "task: " (:task evt))
  :event/progress  (str "msg: " (:message evt))
  :event/completed "done")

Compile-time error if:
- Any variant is missing (non-exhaustive)
- Any unknown variant is listed (typo detection)
sourceraw docstring

adt-dataclj/s

(adt-data x)

Extract the data fields from an ADT value (everything except :adt/type and :adt/variant).

Extract the data fields from an ADT value (everything except :adt/type and :adt/variant).
sourceraw docstring

adt-typeclj/s

(adt-type x)

Extract the type keyword from an ADT value.

Extract the type keyword from an ADT value.
sourceraw docstring

adt-valid?clj/s

(adt-valid? x)

True if x is a valid ADT value with a registered type and known variant.

True if x is a valid ADT value with a registered type and known variant.
sourceraw docstring

adt-variantclj/s

(adt-variant x)

Extract the variant keyword from an ADT value.

Extract the variant keyword from an ADT value.
sourceraw docstring

adt?clj/s

(adt? x)

True if x is any ADT value (has :adt/type and :adt/variant keys).

True if x is any ADT value (has :adt/type and :adt/variant keys).
sourceraw docstring

coerce-keywordclj/s

(coerce-keyword type-kw variant-kw)

Coerce a keyword to an ADT variant value (no data fields). Returns nil if the keyword is not a valid variant of the type.

(coerce-keyword :EventType :event/started) => {:adt/type :EventType, :adt/variant :event/started}

Coerce a keyword to an ADT variant value (no data fields).
Returns nil if the keyword is not a valid variant of the type.

(coerce-keyword :EventType :event/started)
=> {:adt/type :EventType, :adt/variant :event/started}
sourceraw docstring

defadtclj/smacro

(defadt type-name docstring? & variants)

Define a closed algebraic data type (sum type) with keyword dispatch.

Each variant is either:

  • A bare keyword (enum variant, no associated data)
  • A vector [keyword schema-map] (data variant with typed fields)

Generates:

  • TypeName var with type metadata {:type :TypeName :variants #{...} :schemas {...}}
  • type-name constructor fn (kebab-case of TypeName)
  • type-name? predicate fn
  • ->type-name keyword coercion fn (returns nil for invalid keywords)

Example: (defadt EventType "Event types for hivemind communication." [:event/started {:task string?}] [:event/progress {:message string?}] :event/completed)

(event-type :event/started {:task "X"}) ;; => {:adt/type :EventType, :adt/variant :event/started, :task "X"}

(event-type? x) ;; => true/false

Define a closed algebraic data type (sum type) with keyword dispatch.

Each variant is either:
- A bare keyword (enum variant, no associated data)
- A vector [keyword schema-map] (data variant with typed fields)

Generates:
- `TypeName` var with type metadata {:type :TypeName :variants #{...} :schemas {...}}
- `type-name` constructor fn (kebab-case of TypeName)
- `type-name?` predicate fn
- `->type-name` keyword coercion fn (returns nil for invalid keywords)

Example:
  (defadt EventType
    "Event types for hivemind communication."
    [:event/started   {:task string?}]
    [:event/progress  {:message string?}]
    :event/completed)

  (event-type :event/started {:task "X"})
  ;; => {:adt/type :EventType, :adt/variant :event/started, :task "X"}

  (event-type? x) ;; => true/false
sourceraw docstring

deserializeclj/s

(deserialize m)

Deserialize a plain map to a validated ADT value. Returns the map if valid, nil otherwise.

(deserialize {:adt/type :EventType, :adt/variant :event/started, :task "X"}) => {:adt/type :EventType, :adt/variant :event/started, :task "X"}

Deserialize a plain map to a validated ADT value.
Returns the map if valid, nil otherwise.

(deserialize {:adt/type :EventType, :adt/variant :event/started, :task "X"})
=> {:adt/type :EventType, :adt/variant :event/started, :task "X"}
sourceraw docstring

make-variantclj/s

(make-variant type-kw variant-kw)
(make-variant type-kw variant-kw data)

Construct an ADT variant value. Low-level constructor — prefer the generated constructor from defadt for validation.

(make-variant :EventType :event/started {:task "X"}) => {:adt/type :EventType, :adt/variant :event/started, :task "X"}

Construct an ADT variant value. Low-level constructor — prefer the
generated constructor from defadt for validation.

(make-variant :EventType :event/started {:task "X"})
=> {:adt/type :EventType, :adt/variant :event/started, :task "X"}
sourceraw docstring

register-type!clj/s

(register-type! type-kw type-meta)

Register an ADT type with its variant set and schemas. Called by defadt macro — not for direct use.

Register an ADT type with its variant set and schemas.
Called by defadt macro — not for direct use.
sourceraw docstring

registered-typesclj/s

(registered-types)

Return the map of all registered ADT types.

Return the map of all registered ADT types.
sourceraw docstring

serializeclj/s

(serialize x)

Serialize an ADT value to a plain map (EDN-safe). This is effectively identity since ADT values ARE plain maps, but ensures the return is a plain hash-map (not a record or subtype).

Serialize an ADT value to a plain map (EDN-safe).
This is effectively identity since ADT values ARE plain maps,
but ensures the return is a plain hash-map (not a record or subtype).
sourceraw docstring

type-registered?clj/s

(type-registered? type-kw)

True if the given type keyword is registered.

True if the given type keyword is registered.
sourceraw docstring

type-variantsclj/s

(type-variants type-kw)

Return the set of variant keywords for a registered type. Returns nil if type is not registered.

Return the set of variant keywords for a registered type.
Returns nil if type is not registered.
sourceraw docstring

validateclj/s

(validate type-meta x)

Validate an ADT value against its type's schema. Returns the value if valid, throws ex-info if invalid. Use for boundary validation (API entry points, deserialization).

type-meta is the var value from defadt (e.g. EventType).

(validate EventType (event-type :event/started {:task "X"})) => {:adt/type :EventType, :adt/variant :event/started, :task "X"}

Validate an ADT value against its type's schema.
Returns the value if valid, throws ex-info if invalid.
Use for boundary validation (API entry points, deserialization).

type-meta is the var value from defadt (e.g. EventType).

(validate EventType (event-type :event/started {:task "X"}))
=> {:adt/type :EventType, :adt/variant :event/started, :task "X"}
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close