Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mk-session docstring: document sources #477

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/main/clojure/clara/rules.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,17 @@
(defmacro mk-session
"Creates a new session using the given rule sources. The resulting session
is immutable, and can be used with insert, retract, fire-rules, and query functions.

If no sources are provided, it will attempt to load rules from the caller's namespace,
which is determined by reading Clojure's *ns* var.

`sources-and-args` can start with 0+ sources, each being either a namespace symbol or
Copy link
Collaborator

@mrrodriguez mrrodriguez Mar 15, 2023

Choose a reason for hiding this comment

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

I think this is an improvement to the doc string overall.

I do think it's a bit more strict in the doc string than the actual fn is though.

The concept of a "rule source" is protocol-based. The caller could give other data types that represent rule sources.

There is a clara.rules.compiler/IRuleSource protocol that has a few built-in extensions to it for things like clojure.lang.Symbol as can be seen here. People can extend it to other things, eg. clojure.lang.Var types if they wanted to (I've done this before). If what is given does not satisfy this protocol, then it is assumed to indeed be a sequence of rule/query (aka "production") data structures. This logic can be observed here.

a sequence of rules. If no sources are provided, it will attempt to load rules from the
caller's namespace, which is determined by reading Clojure's *ns* var.

Examples: `(mk-session)`, `(mk-session 'my.ns)`, `(mk-session [my-rule])`, `(mk-session 'ns1 [rule2] :cache false)`

This will use rules defined with defrule, queries defined with defquery, and sequences
of rule and/or query structures in vars that are annotated with the metadata ^:production-seq.

The caller may also specify keyword-style options at the end of the parameters. Currently five
The caller may also specify keyword-style options at the end of `sources-and-args`. Currently five
options are supported, although most users will either not need these or just the first two:

* :fact-type-fn, which must have a value of a function used to determine the logical type of a given
Expand All @@ -344,10 +347,10 @@

This is not supported in ClojureScript, since it requires eval to dynamically build a session. ClojureScript
users must use pre-defined rule sessions using defsession."
[& args]
(if (and (seq args) (not (keyword? (first args))))
`(com/mk-session ~(vec args)) ; At least one namespace given, so use it.
`(com/mk-session (concat [(ns-name *ns*)] ~(vec args)))))) ; No namespace given, so use the current one.
[& sources-and-args]
(if (and (seq sources-and-args) (not (keyword? (first sources-and-args))))
`(com/mk-session ~(vec sources-and-args)) ; At least one namespace given, so use it.
`(com/mk-session (concat [(ns-name *ns*)] ~(vec sources-and-args)))))) ; No namespace given, so use the current one.

#?(:clj
(defmacro defsession
Expand Down