Skip to content

feat: implement Clojure hierarchy semantics #308

Description

@csm

Summary

The hierarchy API is publicly registered but mostly consists of stubs:

  • derive and underive return nil without updating a hierarchy.
  • ancestors and descendants return empty sets.
  • parents always returns nil.
  • isa? checks equality only and supports only two arguments.

The gap is also listed in TODO.md Phase 14.

Reproduction

(derive :example/child :example/parent)
(isa? :example/child :example/parent)
;; actual: false
;; expected: true

(ancestors :example/child)
;; actual: #{}
;; expected: #{:example/parent}

Existing foundation

make-hierarchy already returns the standard-shaped map:

{:parents {} :descendants {} :ancestors {}}

The compatibility suite already contains substantial ancestors, descendants, and underive coverage, but those sections are skipped for the :rust platform.

Suggested scope

  1. Implement explicit hierarchy operations:
    • (derive h tag parent)
    • (underive h tag parent)
    • (isa? h child parent)
    • two-argument parents, ancestors, and descendants
  2. Implement the global hierarchy arities.
  3. Maintain transitive ancestor and descendant closures.
  4. Reject cycles and invalid hierarchy shapes.
  5. Preserve Clojure behavior for vector dispatch values if supported by the current multimethod implementation.

Acceptance criteria

  • Global and explicit-hierarchy arities match Clojure for keyword and symbol tags.
  • Derivation cycles are rejected.
  • Removing an edge correctly recomputes transitive closure, including diamond hierarchies.
  • Relevant :rust skips in the compatibility suite are removed.
  • Multimethod dispatch continues to pass existing tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions