You can indent a code block by 2 spaces to format it as code.
---
Your idea of types is similar to Predicate Dispatch[1]. I believe it's also similar to Racket's contracts[2].
This is an extremely powerful type system in the sense that you can express literally anything with it. However, I believe that a more restrictive type system can actually be better, because it provides more guarantees (especially at compile-time).
---
I don't think it's possible to pattern match on a function's arguments, body, and closure, simply because Racket doesn't expose those things.