Skip to content

Instantly share code, notes, and snippets.

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 olivergeorge/584b54fe0b1d4c6ce3c7a44ee8c29095 to your computer and use it in GitHub Desktop.
Save olivergeorge/584b54fe0b1d4c6ce3c7a44ee8c29095 to your computer and use it in GitHub Desktop.
Type checking function body via generators

Problem

Given some function specs we would like to know if there are bugs in a function definition associated with invalid function calls.

Example

(s/fdef foo :args (s/cat :x number? :y number?) :ret string?)
(s/fdef bar :args (s/cat :z coll?) :ret number?)

(defn baz []
  (let [a (foo 1 2)]
        b (bar a)]
    b))

In this specific example, we would like to check that a (the value returned from the call to foo) will always satisfy the :arg spec for bar.

Reframing as generative check

Stated another way: we need to check that the string? generator produces values which satisfies the coll? predicate.

We can do that by generating values and testing them using s/exercise and s/valid?.

Cache facts & examples

We can also cache the output in case we come across this combination again.

Additionally, we can keep examples of values which don't validate to improve error messages with a concrete example.

Unresolved

  • What about transitive stuff? Are specs insufficient to catch case where a function's input type relates to it's output type.
  • Specs are typically defined/available after function is declared. That means analysis would need to be a separate sweep.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment