Fork me on GitHub
#conjure
<
2020-07-19
>
Olical16:07:51

I'm experimenting with multiple connections for every client 👀 thanks to the #105 issue forcing me to think about the concept and how I could slot it in seamlessly.

Olical17:07:31

Adding a dynamic var system to handle binding things other than the current client in call stacks too! So small! And tested!

(module conjure.dynamic
  {require {a conjure.aniseed.core}})

(def- stack-key :conjure.dynamic/stack)

(defn new [base-value]
  (let [stack [base-value]]
    (fn [x ...]
      (if (= stack-key x)
        stack
        ((a.last stack) x ...)))))

(defn- run-binds! [f binds]
  (a.map-indexed
    (fn [[dyn new-value]]
       (f (dyn stack-key) new-value))
    binds))

(defn bind [binds f ...]
  (run-binds! table.insert binds)
  (let [(ok? result) (pcall f ...)]
    (run-binds! #(table.remove $1) binds)
    (if ok?
      result
      (error result))))

Olical17:07:18

Really happy with it, it means I can replace the current conjure.client/with-filetype implementation with something robust, nestable and generic.

Olical17:07:56

These are all internal things but really good progress towards having as many connections as you want per client with easy ways to switch between them 😄

Olical17:07:32

This allows me to do (def filetype (dyn.new #(.filetype)) for example, then (filetype) to get the current filetype. Then I can use (dyn.bind {filetype #(do :something-else)} some-body-function) to override it in a call stack local way!

Olical17:07:15

This is basically a poor imitation of Clojure's dynamic vars and binding but still, it's useful.