Skip to content

Instantly share code, notes, and snippets.

@fanannan
Created March 16, 2014 06:10
Show Gist options
  • Save fanannan/9579272 to your computer and use it in GitHub Desktop.
Save fanannan/9579272 to your computer and use it in GitHub Desktop.
(ns schema-test.core
(:require
; Schema
[schema.core :as s] ; 型チェック関係
[schema.macros :as sm] ; 定義用マクロなど
))
;;
;; validate, check
;;
; java.lang直下のクラス(instance?)
; クラス/インターフェース一般
(s/validate Number 42)
(s/validate Long 42)
(s/validate Double 42.0)
(s/check Boolean :true)
(s/check Character \,)
(s/check String "hello")
(s/validate java.lang.String "schema")
(s/validate Ratio 5/8)
(s/validate clojure.lang.Ratio 5/8)
(s/validate clojure.lang.AFn (fn[]))
(s/validate clojure.lang.IFn (fn[]))
(s/validate Runnable (fn[]))
; ClojureScript
(s/validate Element document.getElementById("some-div-id"))
; Schemaでの定義
(s/validate s/Keyword :key)
(s/validate s/Int 42)
(s/validate s/Any 42)
; その他のSchema.coreでの定義をdefしてみる
(def Regex s/Regex)
(def Inst s/Inst)
(def Uuid s/Uuid)
(s/validate Regex #".*")
; シーケンス
(s/validate [Number] [1 2 3.0])
(s/validate [Number] (list 1 2 3.0))
; either
(def Vector (s/either clojure.lang.APersistentVector clojure.lang.LazilyPersistentVector))
(s/validate Vector [1 2 3.0])
; ついでに
(def Seq (s/either clojure.lang.ASeq clojure.lang.LazySeq))
(def Map clojure.lang.APersistentMap)
(def Set clojure.lang.APersistentSet)
; enum
(s/validate (s/enum :a :b :c) :a)
; pred
(def Nil (s/pred nil?))
(def False (s/pred false? 'false-question))
(def Fn (s/pred fn? 'fn?))
(s/validate Nil nil)
(s/check False nil)
(s/validate Fn cons)
(s/validate Fn (fn[x](+ x 1)))
(s/validate Fn #(+ % 1))
; both
(def PosNum (s/both Number (s/pred pos? 'pos?)))
(s/validate PosNum (#(+ % 1) 5))
(s/validate [(s/both String (s/pred (comp odd? count)))] ["a" "aaa" "aaaaa"])
; maybe
(s/validate (s/maybe clojure.lang.Symbol) nil)
; Map
(s/validate {:name String, :id s/Int} {:name "Bob", :id 42})
(s/validate {:name String, s/Any s/Any} {:name "Bob", :age 42})
(s/validate {:name String, (s/optional-key :attr) s/Any} {:name "Bob"}) ;, :attr 1})
(s/validate {(s/enum :a :b :c) Number} {:a 1 :b 2 :c 3})
(def Korma-DB {:pool s/Any,
:options {:naming {:keys s/Any :fields s/Any},
:delimiters s/Any,
:alias-delimiter s/Any,
:subprotocol s/Any}})
(def Korma-Naming {:keys s/Any :fields s/Any})
(def Korma-Options {:naming Korma-Naming,
:delimiters s/Any,
:alias-delimiter s/Any,
:subprotocol s/Any})
(def Korma-DB {:pool s/Any,
:options Korma-Options})
;
; sm/defn
;
(defn f1[x](+ x 1))
(f1 1)
(sm/defn f2[x](+ x 2))
(f2 1)
(sm/defn f3
[x :- Long]
(+ x 3))
(f3 1)
(s/with-fn-validation
(f3 1.0))
(sm/defn f4 :- Long
"SAMPLE DOCSTRING"
[x :- Long]
(str (+ x 3)))
(f4 1)
(s/with-fn-validation
(f4 1))
(sm/defn ^:always-validate f4b :- Long
[x :- Long]
(str (+ x 3)))
(f4b 1)
; destructuring
(sm/defn foo1 [{:keys [x :- Number]}](+ x 3))
(sm/defn foo2 [{:keys [x]} :- {:x Number}](+ x 3))
(sm/defn boo1 [[x :- Number, y :- Number]](+ x 3))
(sm/defn boo2 [[x, y] :- [Number]](+ x 3))
; s/fn-schema, Type-Hint
(s/fn-schema f4)
(s/fn-schema (sm/fn [x :- Long] (str (+ x 1))))
(s/fn-schema (sm/fn f5 :- String [x :- Long] (str (+ x 1))))
(s/fn-schema (sm/fn f6 [^Long x] (str (+ x 1))))
(s/fn-schema (sm/fn f7 [^{:s [Long]} x] (apply + x)))
((sm/fn f7 [^{:s [Long]} x] (apply + x)) [1 2 3])
(meta #'f4)
; record
(sm/defrecord FooBar [foo :- Long, bar :- String])
;(schema.utils/class-schema FooBar)
(s/validate FooBar (FooBar. 1 "2") )
; ベンチマーク
(require '[clojure.core.typed :as ty])
(require '[criterium.core :as cr])
(defn no-check [x](+ x 1))
; quick-bench : 29.89ns ±2.25ns
; bench : -73.68 ±0.41ns
(defn pre-check [x]{:pre [(number? x)]}(+ x 1))
; quick-bench : 35.27223ns ±3.84ns
; bench : -68.39ns ±0.77ns
(defn body-check [x](when (number? x)(+ x 1)))
; quick-bench : 34.56ns ±2.01ns
; bench : -68.22ns ±0.71ns
(defn hint [^Number x](+ x 1))
; quick-bench : 29.80ns ±1.41ns
; bench : -73.40ns ±0.67ns
(defn ^Number hint2 [^Number x](+ x 1))
; quick-bench : -70.92ns ±4.7ns
; bench : -73.24ns ±0.8ns
(ty/ann typed-check [Number -> Number])
(defn typed-check [x](+ x 1))
; quick-bench : -58.2878 8.56
; bench : -71.58 ±0.58ns
(sm/defn schema-no-check [x](+ x 1))
; quick-bench : 38.47ns ±5.39ns
; bench : -62.78ns ±2.02ns
(sm/defn schema-arg-check [x :- Number](+ x 1))
; quick-bench : 38.24ns ±1.70ns
; bench : -65.58 ±0.96ns
(sm/defn schema-arg-check2 :- Number [x :- Number](+ x 1))
; quick-bench : -58.86ns ±n7.14s
; bench : -64.19ns 0.644
(sm/defn ^:always-validate schema-always-arg-check [x :- Number](+ x 1))
; quick-bench : 785.97ns ±23.97ns
; bench : 624.11ns ±33.97ns
;(with-out-str (cr/quick-bench (list 1 1)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment