Download - Contracts in-clojure-pete
![Page 1: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/1.jpg)
@jessitron
Types!Tests!
Clojure!
Contractsin
![Page 2: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/2.jpg)
Contracts and Clojure: the Best-Yet Compromise
Between Types and Tests
Philly ETE, 7 April 2015
![Page 3: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/3.jpg)
What do we know?
How do we know it?
…
This code works!
![Page 4: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/4.jpg)
Formal Proofs
Informal Reasoning
Experimental Evidence
![Page 5: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/5.jpg)
def formatReport(data: ReportData): ExcelSheet
// Scala
![Page 6: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/6.jpg)
types
![Page 7: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/7.jpg)
![Page 8: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/8.jpg)
(defn format-report [report-data] …)
![Page 9: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/9.jpg)
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params) format-report))
![Page 10: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/10.jpg)
(defn ad-performance-report [params]
(-> (fetch-events params)
(analyze-ad-performance params)
format-report))
![Page 11: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/11.jpg)
(defn analyze-ad-performance [events params] (-> events (group-up params) summarize add-total-row (add-headers params)))
(defn ad-performance-report [params]
(-> (fetch-events params)
(analyze-ad-performance params)
![Page 12: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/12.jpg)
{:when 12:34:56 7/8/90 :what "show" :who "abc123"}
![Page 13: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/13.jpg)
{:when org.joda.time.DateTime :what java.lang.String :who java.lang.String}
(def Event )
![Page 14: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/14.jpg)
(def Event )
{:when DateTime :what s/Str :who s/Str}
(:require [schema.core :as s])
![Page 15: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/15.jpg)
(def Event )
{:when DateTime :what Incident :who Customer}
(:require [schema.core :as s])
Event
![Page 16: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/16.jpg)
(def Event )
{:when DateTime :what Incident :who Customer}
(:require [schema.core :as s])
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
![Page 17: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/17.jpg)
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params) format-report))
![Page 18: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/18.jpg)
[Event]
…)(s/defn fetch-events [params]
![Page 19: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/19.jpg)
[Event]
(:require [schema.core :as s])
…)
(s/defn fetch-events[params]
:-
![Page 20: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/20.jpg)
(deftest fetch-events-test … (= (expected (fetch-events input))))
![Page 21: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/21.jpg)
(deftest fetch-events-test … (= (expected (fetch-events input))))
(use-fixtures schema.test/validate-schemas)
![Page 22: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/22.jpg)
(def Event )
{:when DateTime :what Incident :who Customer}
(:require [schema.core :as s])
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
![Page 23: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/23.jpg)
(def Event )
{:when DateTime :what Incident :who Customer}
(:require [schema.core :as s])
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
[[Event]]
![Page 24: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/24.jpg)
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
[[Event]][Event]
![Page 25: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/25.jpg)
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
[[Event]]
[Event]
![Page 26: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/26.jpg)
[Event]
(defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params)
[[Event]]
[[Event] Summation]
![Page 27: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/27.jpg)
[Event]
[( one [Event] ) ( one Summation )]
[[Event]]
![Page 28: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/28.jpg)
[Event]
[(s/one [Event] "event list") (s/one Summation "group sum")]
[[Event]]
![Page 29: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/29.jpg)
(def Group )
[Event]
[(s/one [Event] "event list") (s/one Summation "group sum")]
[[Event]] [Group]
![Page 30: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/30.jpg)
[Event] [[Event]]
{:groups [Group]}
![Page 31: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/31.jpg)
[Event] [[Event]]
{:groups [Group] :totals Totals}
![Page 32: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/32.jpg)
[Event] [[Event]]
{:header Headers :groups [Group] :totals Totals}
![Page 33: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/33.jpg)
[Event] [[Event]]
{:header Headers :groups [Group] :totals Totals}
(def ReportData
)
![Page 34: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/34.jpg)
{:header Headers :groups [Group] :totals Totals}
(def ReportData
)
(s/defn analyze-ad-performance :- [events :- params :- Params] (-> events (group-up params) summarize add-total-row (add-headers params)))
![Page 35: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/35.jpg)
ReportData(s/defn analyze-ad-performance :- [events :- params :- Params] (-> events (group-up params) summarize add-total-row (add-headers params)))
[Event]
![Page 36: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/36.jpg)
(deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance events {}) (is (= expected (:groups result))))))
(s/defn analyze-ad-performance :-
params :- Params]
(group-up params)
add-total-row (add-headers params)))
![Page 37: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/37.jpg)
(deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance events {}) (is (= expected (:groups result))))))
(use-fixtures schema.test/validate-schemas)
![Page 38: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/38.jpg)
(let [… result (analyze-ad-performance events {}) (is (= expected (:groups result))))))
Input does not match schema Params
Missing required key :title Missing required key :start Missing required key :end
![Page 39: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/39.jpg)
:title string:start date:end date
Params
![Page 40: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/40.jpg)
:title string:start date:end date
:title string:start date:end date
param-gen
![Page 41: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/41.jpg)
:title string that isn't empty:start date before end date:end date before now
:title string:start date:end date
:title string:start date:end date
param-gen
![Page 42: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/42.jpg)
:title string that isn't empty:start date before end date:end date before now
:title string:start date:end date
param-gen
![Page 43: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/43.jpg)
(deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance [events] (sample-one param-gen)) (is (= expected (:groups result))))))
![Page 44: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/44.jpg)
(defspec analyze-ad-performance-spec 100 (for-all [events events-gen params param-gen] (analyze-ad-performance events params))))
![Page 45: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/45.jpg)
Q: What do we know?
A: Schemas
Q: How do we know it?
A: Generative Tests
![Page 46: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/46.jpg)
Q: What do we know?
data shape
![Page 47: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/47.jpg)
We live in this weird time where a rose by any other name throws a compile/runtime error. @deech
![Page 48: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/48.jpg)
Q: What do we know?
data shape
data value boundaries
![Page 49: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/49.jpg)
:title - string - not empty - capitalized
Headers
![Page 50: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/50.jpg)
(def Headers {:title (s/both s/Str (s/pred (complement empty?) "nonempty") (s/pred capitalized? "Title Caps")) …})
![Page 51: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/51.jpg)
Q: What do we know?
data shape
value boundaries
relationships within values
![Page 52: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/52.jpg)
{:title … :start DateTime :end DateTime} - start is before end
Headers
![Page 53: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/53.jpg)
Q: What could we know?
produced types
![Page 54: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/54.jpg)
(s/def params :- (generator-of Params) (gen/hash-map :title … :start … :end …))
what
if?
![Page 55: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/55.jpg)
(defgen params Params (gen/hash-map :title … :start … :end …))
what
if?
![Page 56: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/56.jpg)
(defgen params Params (gen/hash-map :title … :start … :end …))
what
if?
Generator: my-project.generators/params Value: {:end #<DateTime -58693684-08-30T03:25:35.104Z>, :start #<DateTime -71419883-06-14T11:43:44.640Z>, :title ""} Error: (not (keyword? a-clojure.lang.PersistentArrayMap))
![Page 57: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/57.jpg)
(s/defn fetch-events :- [Event] [params] …)
![Page 58: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/58.jpg)
(s/defn fetch-events :- (lazy-seq-of Event) [params] …)
what
if?
![Page 59: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/59.jpg)
Generator of A
Function from A to B
Lazy sequence of A
![Page 60: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/60.jpg)
Q: What could we know?
produced types
relationships between types
![Page 61: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/61.jpg)
(s/defn sample-one [A :- Schema] (s/fn :- A [g :- (generator-of A)] (last (gen/sample g))))
((sample-one Params) params-gen)
![Page 62: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/62.jpg)
(tdefn sample-one :- A [A :- Schema g :- (generator-of A)] (last (gen/sample g)))
what
if?
(sample-one Params param-gen)
(sample-one param-gen)
![Page 63: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/63.jpg)
what
if?(tdefn add-headers :- (merge A {:header Headers}) [data-so-far :- [A :< AnyMap] params])
![Page 64: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/64.jpg)
what
if?
(add-headers data params)
(add-headers GroupsWithTotal data params)
(tdefn add-headers :- (merge A {:header Headers}) [data-so-far :- [A :< AnyMap] params])
![Page 65: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/65.jpg)
Q: What could we know?
produced types
relationships between types
relationships between values
![Page 66: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/66.jpg)
(defn group-up [events params] {:post [(as-lazy-as events %)] …))
![Page 67: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/67.jpg)
relationships between types
produced types
relationships between values
data shape
data value boundaries
relationships within values
![Page 68: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/68.jpg)
![Page 69: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/69.jpg)
![Page 70: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/70.jpg)
(def Event {:when DateTime :what Incident :who Customer})
(s/defn fetch-events :- [Event] [params] …)
![Page 71: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/71.jpg)
(def Event {:when DateTime :what Incident :who Customer})
(s/defn fetch-events :- [t/Event] [params] …)
(:require [my-project.schemas :as t])
my-project.schemas
![Page 72: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/72.jpg)
implementation
schemas
![Page 73: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/73.jpg)
implementation
schemas
src
![Page 74: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/74.jpg)
(def params (hash-map :title gen/string-alpha-numeric :start (datetime-before (now)) :end (datetime-before (now))))
(defspec analyze-ad-performance-spec 100 (for-all [events mygen/events params mygen/params] (analyze-ad-performance events params))))
(:require [my-project.gen :as mygen])
my-project.gen
![Page 75: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/75.jpg)
tests
generators
![Page 76: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/76.jpg)
test
tests
generators
![Page 77: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/77.jpg)
test
tests
generators
![Page 78: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/78.jpg)
test
tests
generators
implementation
schemas
src
![Page 79: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/79.jpg)
test
tests
generators
implementation
schemas
src
![Page 80: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/80.jpg)
test
tests
generators
implementation
schemas
src
src testclient
![Page 81: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/81.jpg)
test
tests
generators
implementation
schemas
src
src testclient
![Page 82: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/82.jpg)
implementation
schemas generators
tests
![Page 83: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/83.jpg)
implementation
schemas generators
tests
![Page 84: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/84.jpg)
implementation
schemas
generators
tests
![Page 85: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/85.jpg)
implementation
schemas
generators
tests
![Page 86: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/86.jpg)
implementation
schemas
generators
tests
src testclient
![Page 87: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/87.jpg)
implementation
schemas generators
tests
src test
![Page 88: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/88.jpg)
implementation
schemas
generators
tests
![Page 89: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/89.jpg)
implementation
schemas
generators
tests
src testclient
![Page 90: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/90.jpg)
testkitimplementation
schemas
generators
tests
![Page 91: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/91.jpg)
testkitimplementation
schemas
generators
tests
![Page 92: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/92.jpg)
testkitimplementation
schemas
generators
tests
![Page 93: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/93.jpg)
testkitimplementation
schemas
generators
tests
![Page 94: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/94.jpg)
![Page 95: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/95.jpg)
Executable Specifications
what do we know?
how do we know it?
![Page 96: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/96.jpg)
![Page 97: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/97.jpg)
Science!
test.check
prismatic/schema
Clojure
![Page 98: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/98.jpg)
Science!
generative tests
types and contracts
… your language …
Science!
![Page 99: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/99.jpg)
Science!
in-memory test tools
native API definitions
… your language …
everyone!forScience!
![Page 100: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/100.jpg)
Formal Proofs
Informal Reasoning
Experimental Evidence
![Page 101: Contracts in-clojure-pete](https://reader030.vdocument.in/reader030/viewer/2022032421/55a6394d1a28ab701e8b47c4/html5/thumbnails/101.jpg)
@jessitronblog.jessitron.com
https://github.com/jessitron/contracts-as-types-exampleshttps://github.com/jessitron/slack-client
examples
resourceshttps://github.com/Prismatic/schemahttps://github.com/miner/herbert (value relationships)http://david-mcneil.com/post/114783282473/extending-prismatic-schema-to-higher-order
https://github.com/jessitron/schematron
http://dl.acm.org/citation.cfm?id=2661156Static typing and productivity: Stefik & Hanenberg 2014