Above and beyond type systems with
clojure.spec
Carlo Sciolla
CODEMOTION MILAN - SPECIAL EDITION
10 – 11 NOVEMBER 2017
whoamicommunity edition
whoamienterprise edition
clojure.spec?
What spec is...
- a queryable registry of predicates
- a description of shapes of data
- a library to validate code interaction
- a gateway drug to generative testing
...and what spec is not
- a type
- a type system
- a compiler
- a static interface
- a bug-free code guarantee
SHOW
ME
THE
CODE!!11oneone
WARN: parenthesis ahead!
A Clojure primer
(ns codemotion.demo)
(defn hello-user
[user]
(when (seq user)
(str "Hello, " user "!")))
(hello-user "world")
A Clojure primer
(ns codemotion.demo)
(defn hello-user
[user]
(when (seq user)
(str "Hello, " user "!")))
(hello-user "world")
(hello-user 42)
As clojure is a dynamically typed language, no compile time error is thrown when feeding functions with
unexpected kind of input.
Step 1:
string ok, number nok
We start with a predicate
user> (doc string?)
-------------------------
clojure.core/string?
([x])
Return true if x is a String
user> (string? 42)
false
user> (string? "I'm a string")
true
Predicates are functions that return boolean values. Any predicate can be used as a spec.
Attach the spec to a function
(ns codemotion.demo
(:require [clojure.spec.alpha :as s]))
(defn hello-user!
[user]
(when (seq user)
(str "Hello, " user "!")))
(s/fdef hello-user!
:args (s/cat :user string?))
demo timewish me luck
Function spec at its finest
(s/fdef hello-user!
:args (s/cat :user ::non-blank-string)
:ret ::non-blank-string
:fn (fn [{ret :ret
{user :user} :args}]
(= (count ret)
(+ 9 (count user)))))
You can spec the input arguments, the return value and the function invariants.
Step 2:
complex data types
union types and the likes
Greeting a JWT-authenticated user
demo time
wish me luck
Step 3:
generative testing
demo timebla bla bla.. ok, we got it
Conclusions
Philosophy and philology of
Philosophy and philology of
[Lisp] has assisted a number of our most gifted fellow humans in thinking previously impossible
thoughts
E. W. Dijkstra
Philosophy and philology of
We were not out to win over the Lisp programmers; we were after the C++ programmers. We managed
to drag a lot of them about halfway to Lisp
Guy Steele
Philosophy and philology of
[Clojure was] designed to be useful for the work I was doing, where you have customers that have
requirements that things run on one of these standard platforms
Rich Hickey
Philosophy and philology of
People change the world by using things. The focus must be on the "using", not the "thing"
Bret Victor
Thank you!
Carlo Sciolla
Sr Developer
https://codehopper.nl
https://synple.eu
@skuro

Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion Milan 2017

  • 1.
    Above and beyondtype systems with clojure.spec Carlo Sciolla CODEMOTION MILAN - SPECIAL EDITION 10 – 11 NOVEMBER 2017
  • 2.
  • 3.
  • 5.
  • 6.
    What spec is... -a queryable registry of predicates - a description of shapes of data - a library to validate code interaction - a gateway drug to generative testing
  • 7.
    ...and what specis not - a type - a type system - a compiler - a static interface - a bug-free code guarantee
  • 8.
  • 9.
    A Clojure primer (nscodemotion.demo) (defn hello-user [user] (when (seq user) (str "Hello, " user "!"))) (hello-user "world")
  • 10.
    A Clojure primer (nscodemotion.demo) (defn hello-user [user] (when (seq user) (str "Hello, " user "!"))) (hello-user "world") (hello-user 42) As clojure is a dynamically typed language, no compile time error is thrown when feeding functions with unexpected kind of input.
  • 11.
  • 12.
    We start witha predicate user> (doc string?) ------------------------- clojure.core/string? ([x]) Return true if x is a String user> (string? 42) false user> (string? "I'm a string") true Predicates are functions that return boolean values. Any predicate can be used as a spec.
  • 13.
    Attach the specto a function (ns codemotion.demo (:require [clojure.spec.alpha :as s])) (defn hello-user! [user] (when (seq user) (str "Hello, " user "!"))) (s/fdef hello-user! :args (s/cat :user string?))
  • 14.
  • 15.
    Function spec atits finest (s/fdef hello-user! :args (s/cat :user ::non-blank-string) :ret ::non-blank-string :fn (fn [{ret :ret {user :user} :args}] (= (count ret) (+ 9 (count user))))) You can spec the input arguments, the return value and the function invariants.
  • 16.
    Step 2: complex datatypes union types and the likes
  • 17.
  • 18.
  • 19.
  • 20.
    demo timebla blabla.. ok, we got it
  • 21.
  • 22.
  • 23.
    Philosophy and philologyof [Lisp] has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts E. W. Dijkstra
  • 24.
    Philosophy and philologyof We were not out to win over the Lisp programmers; we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp Guy Steele
  • 25.
    Philosophy and philologyof [Clojure was] designed to be useful for the work I was doing, where you have customers that have requirements that things run on one of these standard platforms Rich Hickey
  • 26.
    Philosophy and philologyof People change the world by using things. The focus must be on the "using", not the "thing" Bret Victor
  • 27.
    Thank you! Carlo Sciolla SrDeveloper https://codehopper.nl https://synple.eu @skuro