Search code examples
clojurestatic-typing

shortest Clojure static typing


what is the literal simplest, shortest way to typecheck a clojure function. The regular ann form is pretty short:

(ann bar [Number -> Number])
(defn bar [b]
  (+ 2 (foo b)))

But can we (with a macro or something) make it look smaller, like:

(defn bar [b : Number -> Number]
  (+ 2 (foo b)))

Thanks for your advice!


Solution

  • I think Plumatic Schema is the best. See also this blog post.

    Here is an example:

    (ns tst.demo.core
      (:use tupelo.core tupelo.test)
      (:require [schema.core :as s]))
    
    (s/defn add2 :- s/Num ; "superclass" for any number
      [a :- s/Int ; must be an integer type
       b :- Double] ; Must be a java.lang.Double
      (+ a b))
    
    (dotest
      (throws? (add2 1 2))
      (throws? (add2 1.0 2))
      (is= 3.0 (add2 1 2.0)))
    

    I also have some predefined "types" in addition to the basic ones. For example, tupelo.schema/Keymap is any map with keyword keys. Pair is any vector or sequence of length=2, etc.


    Update

    Please also see my Clojure template project. In particular, the file test/clj/_bootstrap.clj exists for the sole purpose of enabling Plumatic Schema type checks when you type lein test (they are disabled by default, so there is no cost in production).