Now we have a Compiler written in Clojure (ClojureScript) we should explore making compilation phases pluggable. This will allow the development of more powerful tools like source analyzers and type checkers.
Analysis phase seems the most useful phase to expose.
Racket achieves this via macros. http://docs.racket-lang.org/reference/syntax.html
For example, #%module-begin (a macro) can be overridden to perform some custom analysis.
Here is how #%module-begin is used by the compiler.
macroexpands to ...
We can see that module-begin wraps every form in the body of a module.
We can override #%module-begin to perform custom analysis.
This example first expands each form after passing them to #%plain-module-begin, then performs some type checking at compile time with type-check-module-body.
(This example is from Typed Racket, see: Advanced Macrology and the Implementation of Typed Scheme)