Skip to content

Instantly share code, notes, and snippets.

@erdos
Last active November 23, 2016 07:53
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 erdos/0be338627c066aa7c0791f65d42bab00 to your computer and use it in GitHub Desktop.
Save erdos/0be338627c066aa7c0791f65d42bab00 to your computer and use it in GitHub Desktop.
BCUG presentation - we dont need no types

Budapest Clojure User Group - meetup presentation proposal for 2016-11-24

Schema vs. Spec

Validating data in dynamic typed programming languages is an important aspect of making sure our programs are safe and correct. In the short presentation we will take a look at two solutions for validating data in Clojure.

Prismatic Schema is a mature library with simple syntax and strong support in the Clojure ecosystem. The new competitor is core.specs supporting in the core language with promising new features. After the presentation we will discuss personal experiences with the advantages and disadvantages of both solutions.

TODO: slides are to be uploaded on this gist.

@erdos
Copy link
Author

erdos commented Nov 22, 2016

Schema

Primitiv (Leaf) semak

  • s/Int, s/Num, s/Keyword, s/Symbol, s/Bool

Maps

  • required-key and optional-key

Sequeneces

  • s/one, s/optional

Other schemas

  • maybe, enum, eq, pred, conditional, cond-pre, constrained
  • either, both, if, pair
  • rekurziv semak

Osszegzes es belso mukodes

  • LeafSpec, VariantSpec, CollectionSpec

Definiciok

  • s/def
  • s/fn
  • s/defrecord
  • ^:always-validate a fuggveny nevehez

Teszteles

  • with-fn-validation
  • (use-fixtures :once schema-test/validate-schema)
  • kezzel hivva: s/validate (hibat dob), s/check, s/checker
  • *asserts*, set-fn-validation!, set-compile-fn-validation!

Coercion

  • coercer

Extensions

schema-human

schema-generators

  • sample, generate, complete

Sources

@erdos
Copy link
Author

erdos commented Nov 22, 2016

Spec

Basics

  • namespaced keys
  • special value: :s/invalid
  • conform? and valid?

Defining specs

  • s/def

Data

  • types: int?, string?, etc...
  • sequences: s/cat, alt, *, +, ?
  • maps: s/keys and ...
  • sets?
  • records?

Composing specs

  • and, or, spec, keys?

Conformers for coercion

  • s/conform and s/conformer

Generative tests

  • check and gen

@erdos
Copy link
Author

erdos commented Nov 22, 2016

Summary

Schemes and specs are a nice counterpart of types in Clojure used for

  • dokumentation
  • validation
  • testing

@erdos
Copy link
Author

erdos commented Nov 23, 2016

+Title: Schema vs Spec


* Introduction

** This talk

 - My name is _Janos Erdos_ and I am a Java/Clojure programmer at dbx.hu

 - This talk is about two approaches of validating data in Clojure.


** The presentation

_How to run the presentation?_


 1. Use Emacs with =org-mode= org =org-tree-slide-mode=

 2. Start a =boot-clj= repl: http://github.com/boot-clj/boot

 3. Connect with =cider-connect= and run =cider-mode=

 4. Evaluate every forms in the presentation with =C-x e=

#+begin_src clojure
(ns bcug.nov
   (:require [boot.core :as boot]))

(println "hello world")

#+end_src


** Data validation

validacios peldak ide.


* Schema

- Open Sourced by Prismatic in 2014
- Used mainly for data validation

#+begin_src clojure
(in-ns 'bcug.nov)

(boot/set-env! :dependencies [['prismatic/schema "1.1.3"]])

(require '[schema.core :as s])

#+end_src

** Schema usage

We can define schemas and we check for them

#+begin_src clojure
(in-ns 'bcug.nov)

(s/defschema Person
  {:name s/Str
   :age  s/Int})

#+end_src

And validate data with them

#+begin_src clojure
(s/validate Person nil)
(s/validate Person {:name "Me" :age true})
(s/validate Person {:name "Me" :age 25})
#+end_src

Or explain a schema

#+begin_src clojure
(s/explain Person)
#+end_src

** Primitive schemas

- Schemas that do not depend on other schemas
- Examples: =Int, Keyword, Bool, Symbol, Str=

#+begin_src clojure
(s/validate s/Int 23)
#+end_src

There are also ways to create schemas.
Examples: =eq, maybe, enum=

#+begin_src clojure
(s/validate (s/maybe (s/eq 42)) 42)
(s/validate (s/eq 42) 42)
(s/validate (s/enum 1 2 3) 1)
#+end_src clojure

** Data structures as schemas

*** Maps

We can validate keys and values in maps

#+begin_src clojure
(in-ns 'bcug.nov)

(s/validate {s/Keyword s/Str} {:a "Alma"})

#+end_src

And also specify optional or required keys.

#+begin_src clojure
;
(s/def Person
  {(s/optional-key :age)  s/Int
   (s/required-key :name) s/Str})

(s/validate Person {:name "E"})

#+end_src

*** Sequences

#+begin_src clojure
(s/def IntVec [s/Int])

(s/validate IntVec [1 2 2 2])


(s/def Color [(s/one s/Str "mode") (s/one s/Int "r") (s/one s/Int "g") (s/one s/Int "b") (s/optional Double "alpha")])

(s/validate Color ["Piros" 255 0 0])
(s/validate Color ["Atlatszo Piros" 255 0 0 0.3])
#+end_src

** Composing schemas

- pred, conditional, cond-pre, constrained
- either both if pair
- rekurziv semak

** Defining schemas

- For named schemas we use the =def= forms
- For functions we use the =fn= form
- For record we use the =defrecord= form

- We can add =^:always-validate= meta key to toggle validation

** Testing

- =with-fn-validation=
- =use-fixtures :once schema-test/validate-schema=
- s/validate, s/check, s/checker
- *asserts*, set-fn-validation!, set-compile-fn-validation!


** Coercion

- =s/coercer= function

** Generative testing

Use the *schema-generators* library to generate data matching a schema.

** Human readeable schema descriptions

Use the *schema-human* library for human-readable messages.

** Schema overview

- Schema library is a de-facto standard approach with readable and composable schema definitions.

* Spec


#+begin_src clojure
(println "egy")

#+end_src

# Masodik Cim

Miert?

# Harmadik Cim

* Overview

- Alternatives: Example Tests, Types, Schemas, Specs
- Factors: Expressive, Powerful, Integrated, Specification, Testing, Agility, Reach

- Will we move to =core.spec=? Discuss.
o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment