Skip to content

WIP: Explain knot#1254

Draft
frenchy64 wants to merge 3 commits intometosin:masterfrom
frenchy64:explain-knot
Draft

WIP: Explain knot#1254
frenchy64 wants to merge 3 commits intometosin:masterfrom
frenchy64:explain-knot

Conversation

@frenchy64
Copy link
Collaborator

Avoids recreating child schemas for recursive explainers.

@opqdonut opqdonut moved this to 📬 Inbox in Metosin Open Source Backlog Feb 4, 2026
@opqdonut
Copy link
Member

opqdonut commented Feb 4, 2026

do you want an initial review of this already or is it still under progress?

@frenchy64
Copy link
Collaborator Author

@opqdonut an initial review would be good.

The summary is: this attempts to reuse objects in memory as much as possible without changing the arguments to -explain (moving the path to the return function). We can't reuse the result of -explain (because it's closed over by a different path, moving the path param would fix this), but we can reuse the schema itself at recursive points.

Open question: is this schema reuse a way to remove *ref-validators*? Perhaps by caching the result of -validator for refs? Is that too much caching? Alternative is to add options arg to -validator.

Copy link
Member

@opqdonut opqdonut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the complexity is growing a lot here, but I'm not completely opposed to merging something like this. I think we might benefit from a design doc that talks about how the caching works, with comments in the impl pointing to that doc. That way once this theme has been forgotten, we don't accidentally break things while touching these lines.

(-type [_] :ref)
(-type-properties [_] type-properties)
(-into-schema [parent properties [ref :as children] {::keys [allow-invalid-refs] :as options}]
(-into-schema [parent properties [ref :as children] {::keys [allow-invalid-refs ref-id->nested-info] :as options}]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will the contents of nested-info be? Could be documented somewhere. I see at least :rf going in there but do you envision something like :validator being there as well?

rf (-memoize #(schema (?schema) options))
(let [id (-identify-ref-schema ref options)
nested-info (get ref-id->nested-info id)
rf (or (:rf nested-info)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if a better name than rf could now be chosen. Maybe something like deref-this? construct-child-schema?

(-validator [this]
(let [id (-identify-ref-schema this)
id->validator *ref-validators*]
(let [id->validator *ref-validators*]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the complexity with both ref-id->nested-info and *ref-validators* is significant. Could they be combined somehow?

(is (= ["hello" "maailma"]
(mapv (comp peek m/form m/deref-all) (m/children schema)))))))

(deftest recursive-explainer-test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the very concrete test

@opqdonut opqdonut moved this from 📬 Inbox to ⌛Waiting in Metosin Open Source Backlog Feb 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ⌛Waiting

Development

Successfully merging this pull request may close these issues.

2 participants