babashka

stagmoose 2025-05-04T15:03:43.270149Z

has anyone try odoyle on babashka? i can only find one relevant discussion on slack but i can use it with some simple code on babashka without any problem but not sure if it is fully compatible https://clojurians.slack.com/archives/CLX41ASCS/p1605959727433400

✅ 1
borkdude 2025-05-04T15:04:44.181059Z

That link points to something from four years ago, bb has come a long way since then (and now includes clojure.spec.alpha which tripped it up back then it seems)

stagmoose 2025-05-04T15:05:37.256849Z

gocha, thanks michiel!

stagmoose 2025-05-04T15:08:04.606489Z

leave some working snippet for the future explorer: (generated with gemini and can run with no errors)

(ns bb.my-project.main
  (:require [odoyle.rules :as o]))

;; Define the rules for our reactive counter
(def rules
  (o/ruleset
    {;; Rule to increment the counter when a :tick happens
     ::increment-counter
     [:what
      ;; Bind the current counter value.
      ;; {:then not=} ensures this rule only triggers if the counter *value* changes,
      ;; preventing potential issues if we re-inserted the same value,
      ;; and makes it react to the initial insertion.
      [::counter ::value current-value {:then not=}]
      ;; This rule requires a :tick fact to exist. Bind its value.
      [::tick    ::now   tick-id]
      :then
      ;; When triggered, insert the incremented value back into the session.
      ;; Using o/insert! implicitly updates the session within the rule.
      (println "-> Tick received! Incrementing counter...")
      (o/insert! ::counter ::value (inc current-value))
      ;; Retract the specific tick fact that triggered this rule instance.
      (o/retract! ::tick ::now)]

     ;; Rule to print the counter whenever its value changes
     ::print-counter
     [:what
      ;; Bind the counter value. {:then not=} ensures this only triggers
      ;; when the value is different from the previous match for this rule.
      [::counter ::value current-value {:then not=}]
      :then
      ;; Print the new value.
      (println (str "<- Counter changed! New value: " current-value))]}))

;; Initialize the session atom with our rules
(def *session
  (atom (reduce o/add-rule (o/->session) rules)))

(defn initialize-counter! []
  (println "Initializing counter to 0...")
  (swap! *session
         (fn [session]
           (-> session
               ;; Insert the starting value for the counter
               (o/insert ::counter ::value 0)
               ;; Fire rules to process the initial state
               o/fire-rules))))

(defn send-tick! []
  (println "Sending tick...")
  (swap! *session
         (fn [session]
           (-> session
               ;; Insert a :tick fact. Using the current time ensures it's unique
               ;; each time, guaranteeing the ::increment-counter rule can trigger again.
               (o/insert ::tick ::now (System/currentTimeMillis))
               ;; Fire rules to process the tick and subsequent changes
               o/fire-rules))))

;; Main function to run the demo
(defn -main [& _args]
  (println "--- O'Doyle Reactivity Demo ---")
  (initialize-counter!) ; Set up the initial state

  ;; Wait a bit for clarity in output
  (Thread/sleep 1000)
  (send-tick!)          ; Send the first tick

  (Thread/sleep 1000)
  (send-tick!)          ; Send another tick

  (Thread/sleep 1000)
  (send-tick!)          ; And one more

  (println "--- Demo Finished ---"))

;; You can also run these interactively in a REPL connected to Babashka:
;; (initialize-counter!)
;; (send-tick!) 

borkdude 2025-05-04T15:09:30.281949Z

Thanks :)

🙇 1
borkdude 2025-05-04T15:16:11.057729Z

It seems all the unit tests pass:

$ bb -Sdeps '{:paths ["src" "test"] :deps {local/local {:local/root "."}}}' test.clj

Testing odoyle.rules-test

Ran 37 tests containing 107 assertions.
0 failures, 0 errors.

2025-05-04T21:35:14.671289Z

https://blog.michielborkent.nl/babashka-test-runner.html Is there a way to test namespaces that don't end with "-test"? I tried adding :patterns [".*"] in the :exec-args, but then using --nses in the command line doesn't work. 😕

✅ 1
borkdude 2025-05-04T21:53:13.578959Z

Perhaps patterns takes priority over nses in the cognitect test runner?

borkdude 2025-05-04T21:54:21.373009Z

so you have to undo the patterns I guess

borkdude 2025-05-04T21:55:06.004079Z

this seems to work for me:

bb test:bb --nses foo --patterns ''

borkdude 2025-05-04T21:55:23.129709Z

or --patterns nil

2025-05-04T22:04:03.770769Z

Ah yes it works! Thank you very much 🙏