Skip to content

Instantly share code, notes, and snippets.

View stuarthalloway's full-sized avatar

Stuart Halloway stuarthalloway

View GitHub Profile
(defn round5
"Round to the closest positive multiple of 5.
Negative numbers round to 0, which is not
considered a multiple of 5."
{:test (fn [] (let [roundsto (fn [e] #(= e (round5 %)))]
(testing "Negative numbers"
(is (every? (roundsto 0) (range -20 0))))
(testing "Positive numbers rounding to 5"
(is (every? (roundsto 5) (range 0 8))))
(testing "Positive numbers rounding not to 5"
@stuarthalloway
stuarthalloway / pull_in_query.clj
Last active February 1, 2018 13:41
Pull in Query
:find (pull ?e [*])
@stuarthalloway
stuarthalloway / atomic_state_update.clj
Last active November 25, 2017 19:26
Update state with a pure function
;; fixed version of 'state' at http://mishadoff.com/blog/clojure-design-patterns/#episode-3-state
;; takeaway: if you call 'swap!' twice on the same atom, you are probably making a mistake
(def user {:name "Jackie Brown"
:balance 0
:subscription? false})
(def ^:const SUBSCRIPTION_COST 30)
(defn pay
@stuarthalloway
stuarthalloway / missing_keys_specs.clj
Created October 14, 2017 11:44
I think it would be a mistake to introduce temporal coupling to prevent typos.
;; I think it would be a mistake to introduce temporal coupling to prevent typos.
;; The example program below lets you identify "missing" keys specs at
;; the time and place of your choosing, and then handle them as you
;; deem appropriate, without imposing those decisions on other
;; users of spec.
(require '[clojure.spec.alpha :as s]
'[clojure.set :as set])
@stuarthalloway
stuarthalloway / using_reset!.clj
Created October 13, 2017 12:03
Using clojure reset!
;; fix for code shown at https://twitter.com/metcarob/status/918764898041188352
(def recieved-slack-vars (atom {}))
;; unnecessarily complex
(defn return-second-arg [arg1 arg2]
arg2)
(defn set-recieved-slack-vars
[newval]
(swap! recieved-slack-vars return-second-arg newval))
(set-recieved-slack-vars {:botname "Test"})
;; try this form-by-form at a REPL
(require '[clojure.spec.alpha :as s])
;; create an inline DSL to describe the FizzBuzz world
(defmacro divides-by
[nm n]
`(s/def ~nm (s/and pos-int? #(zero? (mod % ~n)))))
;; specify FizzBuzz
(divides-by ::fizz 3)
@stuarthalloway
stuarthalloway / FizzBuzzTestSuite.edn
Created August 12, 2017 22:22
Test Suite for FizzBuzz
(1 2 "Fizz" 4 "Buzz" "Fizz" 7 8 "Fizz" "Buzz" 11 "Fizz" 13 14 "FizzBuzz" 16 17 "Fizz" 19 "Buzz" "Fizz" 22 23 "Fizz" "Buzz" 26 "Fizz" 28 29 "FizzBuzz" 31 32 "Fizz" 34 "Buzz" "Fizz" 37 38 "Fizz" "Buzz" 41 "Fizz" 43 44 "FizzBuzz" 46 47 "Fizz" 49 "Buzz" "Fizz" 52 53 "Fizz" "Buzz" 56 "Fizz" 58 59 "FizzBuzz" 61 62 "Fizz" 64 "Buzz" "Fizz" 67 68 "Fizz" "Buzz" 71 "Fizz" 73 74 "FizzBuzz" 76 77 "Fizz" 79 "Buzz" "Fizz" 82 83 "Fizz" "Buzz" 86 "Fizz" 88 89 "FizzBuzz" 91 92 "Fizz" 94 "Buzz" "Fizz" 97 98 "Fizz" "Buzz")
(require '[clojure.spec.alpha :as s])
(s/def ::coord nat-int?)
(s/def ::x ::coord)
(s/def ::y ::coord)
(s/def ::xy (s/keys :req-un [::x ::y]))
(s/def ::point (s/map-of #{:point} ::xy))
(s/def ::username (s/and string? seq))
(s/def ::user (s/map-of #{:user} ::username))
@stuarthalloway
stuarthalloway / java_tx_fn_in_clojure.clj
Created June 16, 2017 13:48
Java Transaction Function in Clojure
(require '[datomic.api :as d])
(def uri "datomic:mem://foo")
(d/create-database uri)
(def conn (d/connect uri))
(def schema [{:db/ident :foo
:db/fn #db/fn
{:lang "java"
:params [db a b c]
:code "return a;"}}])
(def argses (->> (s/exercise ::cs/xy-chart-args 10 ex/generators)
(mapv first)))