Skip to content

Using Clara from the REPL

rbrush edited this page Oct 9, 2014 · 1 revision

Many Clojure users do development in a REPL or a REPL-connected editor. Clara can participate in this type of workflow cleanly. Rules can be defined and reloaded at any time.

Here is simple session showing the creation and use of a rule in a Clojure REPL:

user=> (require '[clara.rules :refer :all])
nil
user=> (defrecord Person [first last])
user.Person
user=> (defrule say-hello [Person (= ?first-name first)] => (println "Hello," ?first-name))
#'user/say-hello
user=> (-> (mk-session :cache false) (insert (->Person "Jane" "Doe")) (fire-rules))
Hello, Jane
#<LocalSession clara.rules.engine.LocalSession@42d33bc1>
user=> 

An arbitrary number of rules can be defined and used like this. By default (mk-session) will load rules defined in the current namespace, but the caller can pass arbitrary namespaces if desired.

Also note the use of the :cache false option in mk-session. Normally mk-session memoizes the session it creates given a namespace, which is important for performance when creating many sessions. The :cache false option seen here disables that, re-compiling the rules and the session every time it is invoked. This allows users to redefine rules on the fly in the REPL, and they'll appear the next time mk-session is called.

REPL-Connected Editors

Clara rules defined in a given namespace can be reloaded by reloading that namespace. Individual rules can be redfined by re-evaluating the defrule expression.

Of course, the means for doing this depends on the editor. (The original author of Clara typically uses emacs, but this should work in any editor that connects to nrepl.)

Also see the Clara Examples project, which includes rulesets that can be dynamically reloaded if used in a REPL-connected editor.