Skip to content

Instantly share code, notes, and snippets.

@bhb
bhb / repl.txt
Created August 31, 2017 14:30
`:clojure.spec.alpha/spec` is a function, whereas `:pred` is a symbol
If a predicate is passed to `explain-data` directly (to be used as a spec), then the `spec` value is not a symbol, but the function itself.
This makes it tricky to write a consistent printer - I'd like to be able to say "<value> did not match <predicate>" in a consistent way.
user=> *clojure-version*
{:major 1, :minor 9, :incremental 0, :qualifier "alpha19"}
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (::s/spec (s/explain-data string? 1))
#object[clojure.core$string_QMARK___4964 0x125290e5 "clojure.core$string_QMARK___4964@125290e5"]
@bhb
bhb / core.clj
Created August 26, 2017 01:06
Setting up instrumentation on clojure.core with Expound
;; Set up instrumentation somewhere in your project
;; (only need to do this once)
(require '[clojure.core.specs.alpha])
(require '[clojure.spec.alpha :as s])
(require '[clojure.spec.test.alpha :as stest])
(require '[expound.alpha :as expound])
(set! s/*explain-out* expound/printer)
(stest/instrument)
;;; later on ...
@bhb
bhb / repl-buffer-vs-cider-error.txt
Last active July 25, 2017 02:18
An error with output containing single newlines looks different in different cider buffers
// Cider and Cider nrepl 0.15.0
// In *cider-repl localhost*, the formatted string is correct
// because the ^^^ appears right under the value (to highlight the bad value)
-- Spec failed --------------------
(... 123)
^^^
@bhb
bhb / spec_and_macros.clj
Created July 14, 2017 20:25
An example of how you can use specs to build macros.
;; I learned this technique from these posts
;; http://blog.klipse.tech/clojure/2016/10/10/defn-args.html
;; http://blog.klipse.tech/clojure/2016/10/10/defn-args-2.html
;; (which has a lot more details!!!)
;; You must require this to load the core specs
(require '[clojure.core.specs.alpha :as specs])
(require '[clojure.spec.alpha :as s])
(defn my-let* [args]
@bhb
bhb / expound_wrapper.cljs
Created July 14, 2017 18:22
Wrap expound in try/catch
(require '[clojure.spec.alpha :as s])
(require '[expound.alpha :as expound])
;; You'll need to adjust the try/catch error
;; classes for Clojure
;; sp - the spec name
;; v - the value you want to check
(if (s/valid? sp v)
v
@bhb
bhb / map_of.cljs
Created June 26, 2017 14:22
An example of map-of and `in`
;;[org.clojure/clojure "1.9.0-alpha17"]
;;[org.clojure/clojurescript "1.9.542"]
;;[org.clojure/spec.alpha "0.1.123"]
(s/def :foo/user-map (s/map-of string? int?))
(s/explain-data :foo/user-map {"hi" "foo"})
;; Actual value:
;; #:cljs.spec.alpha{:problems
;; ({:path [1],
;; :pred int?,
@bhb
bhb / map_of_ex.cljs
Created June 23, 2017 22:00
A case where the `:in` value is not a path to the value
;;[org.clojure/clojure "1.9.0-alpha17"]
;;[org.clojure/clojurescript "1.9.542"]
;;[org.clojure/spec.alpha "0.1.123"]
(s/def :foo.user/name string?)
(s/def :foo/user (s/keys :req-un [:foo.user/name]))
(s/def :foo/user-map (s/map-of :foo.user/name :foo/user))
(s/explain-data :foo/user-map {"bob" {:age 2 :city "chicago"}})
;; returns the following...
(comment
@bhb
bhb / default_spec.cljs
Created June 21, 2017 02:35
Should I be able to provide a default spec with the `:default` implementation of my multimethod?
;; [org.clojure/clojurescript "1.9.229"]
(s/def :event/type keyword?)
(s/def :search/url string?)
(s/def :error/code int?)
(defmulti event-type :event/type)
(defmethod event-type :event/search [_]
(s/keys :req [:event/type :search/url]))
(defmethod event-type :event/error [_]
(s/keys :req [:event/type :error/code]))
(defmethod event-type :default [_] (s/keys))
@bhb
bhb / example.cljs
Created June 14, 2017 21:18
An example of using `for` vs `map` to apply components
(defn render-cell [{:keys [cellname]}]
(println "cell-name" cellname)
;; Note the key here
[:div {:key cellname}
[:p cellname]])
;; This version works as expected - if I change
;; the second cell, the "println" above only fires for that cell
(defn visible-cells [cells]
[n/view
@bhb
bhb / reagent-state-bidi-input.cljs
Last active June 13, 2017 22:51 — forked from pesterhazy/00-reagent-state-bidi-input.md
Reagent input field experiments in bidirectional binding
(ns klipse-like.core
(:require [reagent.core :as r])
(:import [goog.async Delay]))
(enable-console-print!)
(defonce !state (r/atom nil))
(defn input*
"Like :input, but support on-change-text prop. Avoids mutability pitfalls of