Skip to content

Instantly share code, notes, and snippets.

View candera's full-sized avatar

Craig Andera candera

View GitHub Profile
@candera
candera / README.md
Last active February 13, 2024 10:04
Clojure config files

A little Clojure configuration reader

This is a handy bit of code I've written more than once. I thought I'd throw it in here so I can refer back to it later. Basically, it lets you read a config file to produce a Clojure map. The config files themselves can contain one or more forms, each of which can be either a map or a list. Maps are simply merged. Lists correspond to invocations of extension points, which in turn produces a map, which is merged along with everything else.

An Example

Consider the following files:

names.edn

@candera
candera / setup-encryption.sh
Created February 5, 2013 13:33
Set up transparent encryption in git using openssl
#!/bin/bash
# Sets up transparent encryption of files in /config/private as per
# https://gist.github.com/873637. You will need to edit the password
# in ~/.gitencrypt/password to match everyone else's if you want to
# share this repo.
# Note: due to me being in a hurry, only files in /config/private/ and
# its subdirectories DOWN TO FOUR LEVELS are encrypted.
@candera
candera / Foobar.md
Last active December 14, 2015 07:19
Test gist

title!

Text

image

@candera
candera / SlowInputStream.java
Last active June 30, 2020 12:46
A fairly naive implementation of a slow InputStream. Useful for simulating slow HTTP servers in Ring apps. Also shows how to proxy overloaded methods.
// A Java variation on the same theme
package user;
import java.io.InputStream;
import java.util.Random;
public class SlowInputStream extends InputStream {
private final long time;
private final long size;
@candera
candera / symbolic_composition.clj
Created June 23, 2013 19:35
Sketch of symbolic composition of sound operations
(defn ->op
"Create an operation that just samples that sound
without additional processing."
[s]
(let [s* (gensym "sound")]
`{:bindings {~s* ~s}
:duration (.duration ~s*)
:channels (.channels ~s*)
:amplitude (.amplitude ~s* ~'t ~'c)}))
@candera
candera / graph.clj
Last active December 19, 2015 02:48
A Prismatic Graph for doing sound operations.
{:i1-channels (plumbing/fnk ^long [] 1)
:i1-duration (plumbing/fnk ^double [] 60.0)
:i1-amplitude (plumbing/fnk ^double [^double t] (Math/sin (p/* t 440 2.0 Math/PI)))
:i2-channels (plumbing/fnk ^long [] 1)
:i2-duration (plumbing/fnk ^double [] 60.0)
:i2-amplitude (plumbing/fnk [^double t] (let [x (-> t (p/* 440 2.0) long)]
(if (even? x) 1.0 -1.0)))
:m1-channels (plumbing/fnk ^long [^long i1-channels] i1-channels)
@candera
candera / lein-play
Last active December 19, 2015 16:29
Creates a simple Leiningen project in a throwaway directory, includes dependencies, and starts a REPL.
#!/bin/bash
# Example usage:
#
# lein-play '[org.craigandera/dynne "0.2.0"] [incanter/incanter-core "1.5.1"]'
LIBS=$*
PROJECT_DIR=/tmp/lein-play-`date +%Y%m%d%H%M%S`
mkdir $PROJECT_DIR
@candera
candera / fanout.clj
Created November 19, 2013 21:15
core.async fan-out across n threads
(require '[clojure.core.async :as async])
(let [l (Object.)]
(defn log
[fmt & args]
(locking l
(apply printf fmt args)
(flush))))
(let [req (async/chan 10)
@candera
candera / dopar.clj
Last active February 25, 2020 14:02
dopar
(defn dopar
"Given a (potentially infinite) sequence `coll`, uses core.async to
run `f` for side effects against each value in the collection.
Performs at most `concur` operations in parallel, and never enqueues
more than `lead` items ahead of the ones being consumed. If any call
to `f` throws an exception, it will be rethrown from this function.
Otherwise, returns nil. Optional timeout value is number of
milliseconds to wait for all operations to complete."
([coll f concur lead] (dopar coll f concur lead nil))
([coll f concur lead timeout-ms]
@candera
candera / transact-firehose.clj
Created March 7, 2014 19:30
transact-firehose
;; This has to be a separate function. The way we had it before, with
;; a loop inside a future, creates a closure that captures the head of
;; the sequence. Locals clearing here saves us from that.
(defn- enqueue-transactions
"Transact a (potentially infinite) sequence of transactions on `q`,
reporting status via `status`. Pause for `delay` (if non-nil)
between each transaction."
[conn [tx & more] q status delay]
(if (or (not tx) (:done @status))
(.put q (future :done))