Skip to content

Instantly share code, notes, and snippets.

View vvvvalvalval's full-sized avatar

Valentin Waeselynck vvvvalvalval

View GitHub Profile
@vvvvalvalval
vvvvalvalval / async_promise_listener_hack.clj
Last active August 29, 2015 14:10
Hack for attaching asynchronous callbacks to Clojure promises
(require '[clojure.core.async :as a])
(defn make-promise-listener!
"Creates a function that attaches handlers to Clojure promises.
Behind the scences, fires a loop in another logical thread that scans every refresh-period ms the promises that have been registered for completion,
and executes the each handler on the corresponding value."
[{:keys [refresh-period]
:or {refresh-period 10}}]
(let [next-index! (let [a (atom -1)] #(swap! a inc)) ;; to get unique keys to put in the map.
state (atom {})] ;; map of dummy unique keys to pending promise-handler pairs
@vvvvalvalval
vvvvalvalval / gist:c6c2d991bdc96cce4c14
Last active February 11, 2024 19:34
Asynchronous map function with clojure.core.async
(require '[clojure.core.async :as a])
(defn- seq-of-chan "Creates a lazy seq from a core.async channel." [c]
(lazy-seq
(let [fst (a/<!! c)]
(if (nil? fst) nil (cons fst (seq-of-chan c)) ))))
(defn map-pipeline-async "Map for asynchronous functions, backed by clojure.core.async/pipeline-async .
From an asynchronous function af, and a seq coll, creates a lazy seq that is the result of applying the asynchronous function af to each element of coll.
@vvvvalvalval
vvvvalvalval / monger-populate.clj
Last active August 29, 2015 14:15
'populate foreign keys' functionality with Monger, emulates a subset of Mongoose's populate
(require '[monger.collection :as mc])
(require '[monger.operators :as mop])
(defn populate "Populates the given docs sequence by looking up the 'foreign key' as an :_id in `foreign-coll`.
`foreign-path` can be either a single key or a sequence of keys (as in get-in)
Assumes the foreign keys are ObjectIds or coercable to objectIds.
Returns a seq of the docs where the foreign keys have been updated to be the foreign documents, in the same order.
"
@vvvvalvalval
vvvvalvalval / gist:937f69ef04872b649e82
Created May 25, 2015 12:31
Managing the lifecycle of stateful reagent components with single-item :key-ed seqs
;; Instead of this version, where you have to manage the lifecycle of my-stateful-component with React lifecycle methods
(defn parent-component []
[:div
;; ...
[my-stateful-component dynamic-id arg1 arg2 etc.]
;; ...
])
;; ... you can use this trick
@vvvvalvalval
vvvvalvalval / aynchronous-errors.clj
Last active August 4, 2024 12:45
Asynchronous error management in Clojure(Script)
;; Synchronous Clojure trained us to use Exceptions, while asynchronous JavaScript has trained us to use Promises.
;; In contexts where we work asynchronously in Clojure (in particular ClojureScript), it can be difficult to see a definite way of managing failure. Here are some proposals.
;; OPTION 1: adapting exception handling to core.async CSPs
;; As proposed by David Nolen, with some macro sugar we use Exceptions in go blocks with core async in the same way we would do with synchronous code.
(require '[clojure.core.async :as a :refer [go]])
;; defining some helper macros
(defn throw-err "Throw if is error, will be different in ClojureScript"
@vvvvalvalval
vvvvalvalval / schema-helper-tx-fn.edn
Last active August 29, 2015 14:25
Datomic Schema definition: using transaction function to declare attributes without compromising data-orientation
;; defining helper function
[{:db/id #db/id[:db.part/user]
:db/doc "Helper function for defining entity fields schema attributes in a concise way."
:db/ident :utils/field
:db/fn #db/fn {:lang :clojure
:require [datomic.api :as d]
:params [_ ident type doc opts]
:code [(cond-> {:db/cardinality :db.cardinality/one
:db/fulltext true
:db/index true
@vvvvalvalval
vvvvalvalval / schema_cleaner.clj
Last active August 29, 2015 14:25
discarding unknown key in schema
(ns bs.utils.schema-cleaner "TL;DR look in the tests how the `cleaner` function is used."
(:require [schema.core :as s]
[schema.coerce :as sco]
[schema.utils :as scu]
)
(:use clojure.repl clojure.pprint))
(deftype ^:private GarbageType [])
(def ^:private garbage-const (GarbageType.))
(defmacro m:p "Makes a map from a list of symbols, using the symbol names to create keyword keys.
---
(let [a 1 b 2 c \"3\"]
(m:p a b c))
=> {:a 1, :b 2, :c \"3\"}
" [& syms]
(reduce (fn [m sym]
(assert (symbol? sym) "m:p only accepts symbols")
(assoc m (keyword (name sym)) sym))
{} syms))
@vvvvalvalval
vvvvalvalval / mock-connection.clj
Last active September 19, 2018 06:09
Mocking datomic.Connection for fast in-memory testing
(ns bs.utils.mock-connection
"Utilities for using Datomic"
(:require [datomic.api :as d])
(:use clojure.repl clojure.pprint)
(:import (java.util.concurrent BlockingQueue LinkedBlockingDeque)
(datomic Connection)))
(defrecord MockConnection
[dbAtom, ^BlockingQueue txQueue]
@vvvvalvalval
vvvvalvalval / datomic_datalog_count-related-entities-with-zero-sums.clj
Last active August 27, 2024 14:23
Datomic datalog: counting related entities with 0 sums