Skip to content

Instantly share code, notes, and snippets.

View ghadishayban's full-sized avatar

Ghadi Shayban ghadishayban

View GitHub Profile
(ns day3
(:require [util]))
(defn adjacent-range
"returns [(dec lo), (inc hi)], lo clamped by 0, hi clamped by arg"
[lo hi hi-clamp]
[(max (dec lo) 0)
(min (inc hi) hi-clamp)])
(defn scan-adjacent
;; differences from scheme unfold
;; even initial value is lazy
;; predicate sense reversed
;; internal state == produced value, no special mapper-fn
;; no tail-gen
(defn series
"Produces a sequence of values.
`f` is a function that given a value, returns the next value.
`continue?` is a predicate that determines whether to produce
@ghadishayban
ghadishayban / weighted_rand.clj
Last active September 23, 2022 08:15
Vose's alias method for weighted randoms
(ns weighted-rand
(:import clojure.lang.PersistentQueue))
(defprotocol Rand
(nextr [_ rng]))
;; Vose's alias method
;; http://www.keithschwarz.com/darts-dice-coins/
(deftype Vose [n ^ints alias ^doubles prob]
@ghadishayban
ghadishayban / iteration.clj
Created January 12, 2022 21:43
iteration async
;; needs a refer-clojure exclude on iteration
(defn iteration
"returns a channel of items given step!, a function of some (opaque continuation data) k
step! calls can get bufsize ahead of consumption (asynchronously)
step! - fn of k/nil to chan yielding (opaque) 'ret'
:bufsize - buffer this many step! calls, default 1
:some? - fn of ret -> truthy, indicating there is a value
@ghadishayban
ghadishayban / productions.clj
Last active November 20, 2021 00:06
unified generators
;;
;; Example usages at the bottom of the file
;;
(defn productions
"Returns a sequence of values by repeatedly calling `produce!` until it
returns `fin`. The sequence can be used lazily/caching or reducible/non-caching.
The arity-2 variant's `produce!` takes no arguments and returns a value
or the terminator.
@ghadishayban
ghadishayban / aproto3.ebnf
Last active August 7, 2020 04:00
instaparse is a super power
proto = <syntax> { import | package | option | message | enum | service | emptyStatement } <ws>
(* Header *)
syntax = ws "syntax" ws "=" ws ( "'proto3'" | '"proto3"' ) ws ";"
import = <ws "import" ws> [ "weak" | "public" ] <ws> strLit <ws ";">
package = <ws "package" ws> fullIdent <ws ";">
option = <ws "option" ws> optionName <ws "=" ws > constant <ws ";">
@ghadishayban
ghadishayban / doseq.clj
Created April 24, 2016 05:19
doseq that doesn't blow up with too much bytecode, and w/o (fn []) thunks
(defmacro doseqs
[seq-exprs & body]
(let [stk (gensym "stack__")
level (gensym "level__")
seq-exprs (partition 2 seq-exprs)
bindings (vec (map first seq-exprs))
init-exprs (vec (map second seq-exprs))
nbinds (count init-exprs)
@ghadishayban
ghadishayban / poolboy.clj
Created March 15, 2015 17:23
Interruptible Channels (Needs JDK8)
(ns poolboy.chanfut
(:import [java.util.concurrent CompletableFuture Callable Future]
[java.util.function BiConsumer]
[java.util.concurrent Executor ExecutorService])
(:require [clojure.core.async :as async]
[clojure.core.async.impl.protocols :as async-impl]))
(def async-executor clojure.core.async.impl.exec.threadpool/the-executor)
(defprotocol Interruptible
@ghadishayban
ghadishayban / retry.clj
Last active May 1, 2019 21:41
retry with completablefuture
(ns retry
(:import [java.util.function Supplier]
[java.util.concurrent CompletableFuture TimeUnit]))
(defn with-retry
"given an op wanting retries, and a strategy for backoff,
returns a CompletableFuture that can be waited on
op takes no args
A backoff strategy is a function of an exception, returning nil or a number of milliseconds to backoff"
@ghadishayban
ghadishayban / functional_interfaces.clj
Last active February 4, 2019 17:52
SAM inference helpers
(import '[java.lang.reflect Method Modifier])
(set! *warn-on-reflection* true)
(defn- samsig
"Given a SAM interface, returns the j.l.reflect.Method of the abstract method"
[sym]
(let [kls (resolve sym)]
(if (and (class? kls) (.isInterface ^Class kls))
(let [mid (fn [^Method m] [(.getName m) (vec (.getParameterTypes m))])