Skip to content

Instantly share code, notes, and snippets.

@bhb
Created September 21, 2018 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhb/e8a8d97757e1ef0da04131d41f695c07 to your computer and use it in GitHub Desktop.
Save bhb/e8a8d97757e1ef0da04131d41f695c07 to your computer and use it in GitHub Desktop.
Records vs spec for domain modelling - start with `clj -Srepro -Sdeps '{:deps {expound {:mvn/version "0.7.1"}}}'`
Clojure 1.9.0
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (require '[expound.alpha :as expound])
nil
user=> (set! s/*explain-out* (expound/custom-printer {:theme :figwheel-theme :print-specs? false}))
#object[expound.alpha$custom_printer$fn__897 0x534243e4 "expound.alpha$custom_printer$fn__897@534243e4"]
user=> (s/check-asserts true)
true
user=> (defrecord Person [first-name last-name])
user.Person
user=> ;; invalid type - no error
user=> (map->Person {:first-name 1 :last-name 2})
#user.Person{:first-name 1, :last-name 2}
user=> ;; missing field - no error
user=> (map->Person {:first-name 1})
#user.Person{:first-name 1, :last-name nil}
user=> ;; best case is arity error
user=> (->Person "Jane")
ArityException Wrong number of args (1) passed to: user/eval932/->Person--950 clojure.lang.AFn.throwArity (AFn.java:429)
user=> (s/def :my-app/first-name string?)
:my-app/first-name
user=> (s/def :my-app/last-name string?)
:my-app/last-name
user=> (s/def :my-app/person (s/keys :req-un [:my-app/first-name :my-app/last-name]))
:my-app/person
user=> ;; invalid type error
user=> (s/assert :my-app/person {:first-name 1 :last-name 2})
ExceptionInfo Spec assertion failed
-- Spec failed --------------------
{:first-name 1, :last-name ...}
^
should satisfy
string?
or value
{:first-name ..., :last-name 2}
^
should satisfy
string?
-------------------------
Detected 1 error
clojure.core/ex-info (core.clj:4739)
user=> ;; missing field error
user=> (s/assert :my-app/person {:first-name "Jane"})
ExceptionInfo Spec assertion failed
-- Spec failed --------------------
{:first-name "Jane"}
should contain key: :last-name
| key | spec |
|------------+---------|
| :last-name | string? |
-------------------------
Detected 1 error
clojure.core/ex-info (core.clj:4739)
user=> ;; can reproduce arity error if we want
user=> (defn ->person [first last] (s/assert :my-app/person {:first-name first :last-name last}))
#'user/->person
user=> (->person "Jane")
ArityException Wrong number of args (1) passed to: user/->person clojure.lang.AFn.throwArity (AFn.java:429)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment