Over the past year I have used Prismatic Schema extensively on a large Clojure project. We really like the aid that if offers in understanding, debugging, and using our code. However, we regularly feel a bit of a let down when an argument to a function is another function. Prismatic Schema doesn’t allow you to say much in these cases beyond: this arg is a function.
To address this we extended Prismatic Schema to allow us to add type annotations to the function arguments in higher-order functions (in addition to several other small extensions). This is done by calling s/fn which expects [output-schema & input-schemas]
The type checking for the most part is simply checking that the type of the input function exactly matches the declared type. So the checker largely ignores issues of type hierarchies, covariance, contravariance, etc. As chouser pointed out to me the basic issue this feature raises is that instead of comparing parameter instance objects to declared argument types, this feature requires comparing declared types to declared types. This is one way in which the semantics of this feature are different than “normal” Prismatic schema.
I am torn about the code. On the one hand I am dissatisfied that it is not a full, general solution. On the other hand I can shrug and recognize that for a class of functions and usage patterns it works just fine. So while from a type theoretic perspective it is quite limited, we have started using it and getting benefit from it.