Skip to content

Instantly share code, notes, and snippets.

@bhb
bhb / repro.clj
Created Sep 7, 2018
Changing s/*explain-out* to control spec errors during macro-expansion
View repro.clj
(require '[clojure.spec.alpha :as s])
(set! s/*explain-out* (fn [ed] (println "failed")))
(let [x] 1)
;; with org.clojure/spec.alpha {:mvn/version "0.2.168"} :
;; CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
;; failed
;; #:clojure.spec.alpha{:problems [{:path [:args :bindings :init-expr], :reason "Insufficient input", :pred clojure.core/any?, :val (), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings], :in [0]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2499 0x749c877b "clojure.spec.alpha$regex_spec_impl$reify__2499@749c877b"], :value ([x] 1), :args ([x] 1)}, compiling:(NO_SOURCE_PATH:3:1)
@bhb
bhb / multimethod_selector.clj
Last active Nov 13, 2019 — forked from mtnygard/multimethod_selector.clj
A clojure.spec.gen.alpha generator that picks a multimethod implementation from the known set.
View multimethod_selector.clj
(require '[clojure.spec.gen.alpha :as sgen])
;; original
(defn multimethod-selector
"Returns a generator that picks one dispatch value from the known
dispatch values of a multimethod. Defers the lookup of dispatch
values until sampling time, so any defmethods evaluated after the
generator is created may still be selected."
[s]
#(sgen/bind
@bhb
bhb / ex.clj
Created Aug 23, 2018
Quick hacky idea for generating maps with refs (still has bugs)
View ex.clj
(require '[clojure.test.check.generators :as gen2])
(require '[clojure.spec.alpha :as s])
(s/def :aero/path (s/coll-of simple-keyword? :kind vector? :min-count 1 :max-count 3))
(defn aero-map [paths vals-or-refs backups]
(->> (map vector paths vals-or-refs backups)
(reduce
(fn [m [p [t v] [_ backup-v]]]
(case t
@bhb
bhb / gist:910f718e2da57793bc0f5817f006f28a
Created Jul 17, 2018
`set!` will apply to threads created within REPL
View gist:910f718e2da57793bc0f5817f006f28a
> clj -Sdeps '{:deps {expound {:mvn/version "0.7.1"}}}'
Clojure 1.9.0
user=> (require '[expound.alpha :as expound] '[clojure.spec.alpha :as s])
nil
user=> ;; default printer is used
user=> (future (s/explain int? "a"))
val: "a" fails predicate: :clojure.spec.alpha/unknown
#object[clojure.core$future_call$reify__8097 0x99a65d3 {:status :ready, :val nil}]
user=> (set! s/*explain-out* expound/printer)
#object[expound.alpha$printer 0x4ad4936c "expound.alpha$printer@4ad4936c"]
View gist:c121191c61453bec850a61cc428a109e
clj -Sdeps '{:deps {friendly {:git/url "https://gist.github.com/bhb/2686b023d074ac052dbc21f12f324f18" :sha "c6b0b7cb0a30e2edbf7050c0119ef038cf0f0ac2"}}}' -m friendly
user=> (let [:x 5] x)
Call to clojure.core/let did not conform to spec:
-- Spec failed --------------------
([:x 5] x)
^^
should satisfy
@bhb
bhb / gist:649c46ac6dfa290fa6a62bb96fb66f62
Created Jul 6, 2018
Example of a printer that is more suited for instrumentation
View gist:649c46ac6dfa290fa6a62bb96fb66f62
user=> (require '[expound.alpha :as expound]
'[clojure.spec.alpha :as s])
nil
user=> (set! s/*explain-out* (expound/custom-printer {:print-specs? false :show-valid-values? true}))
#object[expound.alpha$custom_printer$fn__895 0x38b972d7 "expound.alpha$custom_printer$fn__895@38b972d7"]
user=> (let [{:keys 4} foo] x)
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
-- Spec failed --------------------
([{:keys 4} foo] x)
View gist:d82fcf0f80f555c28afa8db320be16c8
Clojure 1.9.0
user=> (def ^:dynamic *x* "foo")
#'user/*x*
user=> *x*
"foo"
user=> ;; binding changes value
user=> (binding [*x* "bar"] *x*)
"bar"
user=> ;; using set! within binding changes value
user=> (binding [*x* "bar"] (set! *x* "bar") *x*)
@bhb
bhb / gist:66804e5fe2a3de728744a620cf0ccf27
Created Jun 25, 2018
Changes in printing alternatives
View gist:66804e5fe2a3de728744a620cf0ccf27
(require '[clojure.spec.alpha :as s])
(require '[expound.alpha :as expound])
(set! s/*explain-out* (expound/custom-printer {:print-specs? false :theme :figwheel-theme}))
;;;;; Old output (0.7.0) ;;;;;
-- Spec failed --------------------
(... (arg1 ...) ...)
^^^^
@bhb
bhb / gist:e8328ce1c15c3fc6f5f4ea71cabfa076
Created May 30, 2018
instrumentation with clojure.spec
View gist:e8328ce1c15c3fc6f5f4ea71cabfa076
➜ ~ clojure -Sdeps "{:deps {com.bhauman/rebel-readline {:mvn/version \"0.1.3\"}}}" -m rebel-readline.main
[Rebel readline] Type :repl/help for online help info
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (s/fdef foo :args (s/cat :x int? :y string?))
user/foo
user=> (defn foo [x y] (prn {:x x :y y}) {y x})
#'user/foo
user=> (require '[clojure.spec.test.alpha :as st])
nil
@bhb
bhb / expound_check.clj
Created Apr 27, 2018
Expound printing mimimized failing input
View expound_check.clj
(require '[expound.alpha :as expound] '[clojure.spec.test.alpha :as st] '[clojure.spec.alpha :as s])
(s/fdef foo :args (s/cat :x pos-int?) :ret (s/int-in 0 5))
(defn foo [x] x)
(set! s/*explain-out* expound/printer)
(expound/explain-results (st/check `foo))
;;== Checked user/foo =========================
;;
;;-- Function spec failed -----------
;;
;; (user/foo 5)