Last active
October 9, 2018 23:52
-
-
Save realgenekim/786b8a1447e36e91f48f901f0317e950 to your computer and use it in GitHub Desktop.
My starting point for ghostwheel type checking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bookserver.io | |
#:ghostwheel.core{:trace true | |
:check false | |
:num-tests 0 | |
; oustrument to check types at run-time for all functions | |
; in this namespace | |
:outstrument true} | |
(:require [clojure.spec.alpha :as s] | |
[ghostwheel.core :as g | |
:refer [>defn >defn- >fdef => | <- ?]])) | |
; human readable spec errors, from expound library | |
(set! s/*explain-out* expound.alpha/printer) | |
; example function | |
(>defn create-hiccup-table-row | |
" take a vector of values [0 2 2 ...], turn them into hiccup " | |
[row] | |
[vector? => | |
; vector of hiccup: [:tr [:td 0] [:td 2] ...] | |
vector?] | |
(->> row | |
(map #(conj [:td] %)) | |
(apply conj [:tr]))) | |
; force tracing, overwriting ns level defaults | |
(>defn ^::g/trace linkify-embed-images-desc | |
[card] | |
[map? => vector?] | |
nil) | |
; @genekim Oh, `::g/trace` is just a regular metadata key like everything else and it's set to 0 by default. | |
; So you just have to attach it to the function like you would any other function metadata in Clojure, so | |
; either `(>defn ^{::g/trace 0} fn-name ...)` or `(>defn fn-name {::g/trace 0} ...}` | |
(>defn ^{::g/trace 0} linkify-embed-images-desc | |
[card] | |
[map? => vector?] | |
nil) | |
; super handy spec is sequential?, which accepts seqs, lists, vectors | |
; (s/nulable sequential?) allows nil values, too. | |
(>defn foo | |
[coll] | |
[(s/nllable sequential?) => sequential?) |
I used to do things like this, to confirm the correct types, which was super-helpful, but sometimes cumbersome to write:
(defn index-of [coll value]
{:pre [(s/valid? coll? coll)]}
(some (fn [[idx item]] (if (= value item) idx))
; [x y z] -> [[0 x] [1 y] [2 z]]
(map-indexed vector coll)))
I find ghostwheel syntax to be much more pleasing and easier to write.
As I have to read or modify code I wrote before, I find myself adding ghostwheel-style typing information, which makes me very happy. Thank you @gnl!
In Java 10, you must require [expound "0.7.1"]
, otherwise you'll get an exception when you (set!)
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Once you've set
:outstrument true
, in a REPL, you can confirm that malformed function args will generate a spec error. Usingexpound
makes errors more human-readable, as well.