Skip to content

Instantly share code, notes, and snippets.

Paul Rutledge RutledgePaulV

Block or report user

Report or block RutledgePaulV

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View let-from-map.clj
(defmacro evaluate* [bindings & code]
(letfn [(eval-with-bindings [bindings code]
(let [ks (keys bindings)]
((eval `(fn [{:syms [~@ks]}] ~code)) bindings)))]
`(~eval-with-bindings ~bindings '(do ~@code))))
@RutledgePaulV
RutledgePaulV / with-redefs.clj
Created Oct 31, 2018
Like with-redefs but local to the thread. Doesn't require dynamic function vars.
View with-redefs.clj
(def ^:dynamic *hook* false)
(defn hook [var f]
(alter-var-root var
(fn [original]
(fn [& args]
(if *hook*
(apply f args)
(apply original args))))))
@RutledgePaulV
RutledgePaulV / hooks.clj
Created Oct 29, 2018
Few functions are dynamic vars. Make them dynamic after the fact by adding a second implementation that only runs for specific threads.
View hooks.clj
(defonce ^:dynamic *hooked* false)
(defn hook [var f]
(alter-var-root var
(fn [original]
(fn [& args]
(if *hooked*
(apply f args)
(apply original args))))))
@RutledgePaulV
RutledgePaulV / cached.clj
Last active Nov 27, 2018
A macro for memoization of a body of code based on the values of all referenced vars (implicit memoization key instead of explicit arguments). Probably a terrible idea.
View cached.clj
(defmacro cached [& body]
(let [dependencies (transient #{})
resolved (walk/postwalk
(fn [form]
(if (symbol? form)
(if-some [resolved (resolve &env form)]
(when (var? resolved)
(conj! dependencies resolved)
(.toSymbol ^Var resolved))
form)
View defqueue.clj
(require '[clojure.core.async :as async])
(require '[mount.core :as mount])
(defn work-queue [buffer max-retries parallelism]
(let [chan (async/chan buffer)]
(dotimes [_ parallelism]
(async/go-loop []
(when-some [i (async/<! chan)]
(let [{:keys [f retries]} (if (map? i) i {:retries 0 :f i})]
(try (f)
@RutledgePaulV
RutledgePaulV / core-async-pipeline-bug.clj
Last active Sep 4, 2018
core-async-pipeline-bug.clj
View core-async-pipeline-bug.clj
(require '[clojure.test :refer :all])
(require '[clojure.core.async :as async])
(deftest from-channel-still-consumed-after-to-channel-is-closed
(let [from-counter (atom 0)
xf-counter (atom 0)
from (async/chan)
to (async/chan 1000)
xf (map #(do (Thread/sleep 100)
(swap! xf-counter inc)
@RutledgePaulV
RutledgePaulV / locking.clj
Created Nov 6, 2017
Some macros for locking by value.
View locking.clj
(def ^:dynamic *locks* (atom {}))
(defn new-lock []
{:count 1 :ref (Object.)})
(defn inc-lock [lock]
(when lock (update lock :count inc)))
(defn dec-lock [lock]
View nor.clj
(defmacro nor [& more]
(conj `~(partition 2 (interleave (repeat 'not) more)) 'and))
View chan-cleanup.clj
(defn attach-channel-cleanup [chan f]
(add-watch (.closed chan)
"channel-resource-cleanup"
(fn [_ _ old-state new-state]
(when (and (not old-state) new-state)
(f))))
chan)
View remove-replace-warnings.clj
; add this to your project.clj file to suppress compilation warnings
:injections
[(alter-var-root clojure.lang.RT/ERR
(constantly
(java.io.PrintWriter.
(org.apache.commons.io.output.NullWriter.))))]
You can’t perform that action at this time.