Skip to content

Instantly share code, notes, and snippets.

View reborg's full-sized avatar

reborg reborg

View GitHub Profile
@reborg
reborg / frequencies-rf-xform.clj
Last active November 19, 2017 17:06
Explorations around frequencies as a reducing function for transducers, sequential or parallel.
(require '[criterium.core :refer [quick-bench]])
(require '[clojure.core.reducers :as r])
(import '[java.util HashMap Collections Map]
'java.util.concurrent.atomic.AtomicInteger
'java.util.concurrent.ConcurrentHashMap)
(set! *warn-on-reflection* true)
;; 500k maps with the same key. value are overlapping 1/5 of the time.
(def data
(into []
;; (defn full-name ...) is equivalent to:
;; (def full-name (fn []...)) which defines a Var
;; object called full-name pointing at a compiled function
;; returning the static string "Oliv"
(defn full-name [] "Oliv")
;; greetings is a function taking two args.
;; it returns a function of no argument
;; invoking the second argument (f) with no arguments
;; and combining a string with it.
;; Interleave transducer. Like the normal interleave, but suitable for transduce.
;; See inlined notes for details. Example at the bottom. If you are interested in this
;; and other similar explorations in and around the standard library, please check my
;; book: https://livebook.manning.com/#!/book/clojure-standard-library/chapter-32/v-10/1
(defn interleave-xform ; <1>
[coll]
(fn [rf]
(let [fillers (volatile! (seq coll))] ; <2>
(fn
@reborg
reborg / ptransducers.clj
Last active May 5, 2019 13:34
Parallel stateful transducers with fold
; The following is an attempt to answer the question: how to use stateful transducers with fork-join r/fold and what you
; should expect. Feedback appreciated. Feel free to discuss on Clojurians slack @reborg.
; Stateful transducers (for example drop, partition-by, dedupe etc.) cannot be used in parallel with fold.
; They produce inconsistent results, for example:
(require '[clojure.core.reducers :as r])
(distinct
(for [i (range 500)]
@reborg
reborg / parallel_java_map_reducers.clj
Last active August 29, 2017 10:38
Updating a java.util.HashMap in parallel with reducers
;; main idea is to create a vector out of the keys
;; and use already existent foldvec to reduce-combine
;; on the key set. Each parallel thread takes an
;; unique set of keys and update the same HashMap
;; instance. "identity" is used as transforming function "f".
;; Just replace with the transformation you need.
(require '[clojure.core.reducers :as r])
(import 'java.util.HashMap)
@reborg
reborg / tic-tac-toe.clj
Last active February 13, 2018 09:32
The ultimate searching winning position tic-tac-toe algo.
;; Playing with conciness and expressivity in Clojure.
;; Not an exercise in efficiency, there are better solutions.
;; It works for different NxN sizes and it's lazy, stopping
;; at the first winning combination for the given player.
(defn winner? [player game]
(let [size (count game)
idxs (range size)]
(->> [[x idx] [idx y] [idx idx] [idx (- (dec size) idx)]]
(map (fn [[x y]] ((game x) y)))
@reborg
reborg / parallel-lazy-merge-sort.clj
Last active November 28, 2017 03:03
Clojure parallel-lazy merge-sort
;; PARALLEL LAZY MERGE-SORT
;; Allows large datasets (that would otherwise not fit into memory)
;; to be sorted in parallel on a single machine.
;; Data to fetch is identified by a range of IDs. IDs are split into
;; chunks that are sent in parallel to a fork-join thread pool
;; (using reducers). A protocol allows to define a policy to fetch
;; the data for the current ID range. The chunk is sorted and saved
;; to disk. A file handle is returned from each thread pointing at
;; a temp file containing the sorted chunk. The list of file handles
@reborg
reborg / rand-remove.clj
Created May 10, 2017 13:52
A few experiments for fast remove random element from a vector/list.
(let [v [0 1 2 3 4 5 6 7]]
(quick-bench
(let [n (rand-int (count v))]
(doall (concat (take n v) (drop (inc n) v))))))
;; 804.634866 ns
(let [v [0 1 2 3 4 5 6 7]]
(quick-bench
(rest (shuffle v))))
;; 181.223551 ns
@reborg
reborg / rich-already-answered-that.md
Last active February 23, 2024 13:09
A curated collection of answers that Rich gave throughout the history of Clojure

Rich Already Answered That!

A list of commonly asked questions, design decisions, reasons why Clojure is the way it is as they were answered directly by Rich (even when from many years ago, those answers are pretty much valid today!). Feel free to point friends and colleagues here next time they ask (again). Answers are pasted verbatim (I've made small adjustments for readibility, but never changed a sentence) from mailing lists, articles, chats.

How to use:

  • The link in the table of content jumps at the copy of the answer on this page.
  • The link on the answer itself points back at the original post.

Table of Content

(def pool (delay (java.util.concurrent.ForkJoinPool.)))
(defn fjtask [^Callable f]
(java.util.concurrent.ForkJoinTask/adapt f))
(defn- fjinvoke [f]
(if (java.util.concurrent.ForkJoinTask/inForkJoinPool)
(f)
(.invoke ^java.util.concurrent.ForkJoinPool
@pool ^java.util.concurrent.ForkJoinTask