I think of Schema as a runtime contracts library (I believe it does coercion and validation, but they seem related to me).
- small barrier to entry, thus immediately useful
- just add a contract/coercion to a function and you're off
- can manipulate contracts as regular clojure data
- documentation
- compatible with the other amazing prismatic libraries (like fn house)
- runtime cost
- contracts often disabled in production
- bug reports have bad errors and stack traces unrelated to the problem
- ... or GIGO
core.typed uses syntactic analysis to avoid certain programming errors. You could theoretically use core.typed to ensure you're using Schema correctly (core.typed needs to learn about Schemas first).
- syntactic assertions
- statically checked documentation
- no runtime cost for typed code
- type checking is slow
- way more complex than contracts
- requires a bigger investment to reap the benefits
- currently turns a blind eye to untyped-typed interaction
- you must provide good annotations for untyped libraries, otherwise things will fail in a similar way to Schema when contracts are disabled
- Typed Racket shows us how to do this, can be fixed (working on it)
- if you forget to actually type check the code, the only benefit is (unchecked) documentation