Raoul,
Refactoring in "modern" dynamic languages is something of an oxymoron
in most contexts. That's slowly changing, as we see progress being
made with refactoring Ruby in the NetBeans environment (with something
similar perhaps in the pipeline there for Python, too). Of course,
there was bicyclerepairman for python some years ago, but I think that
could safely be described as "experimental".
Dynamic languages that operate within an "image" (like Smalltalk, and
many Common Lisps) often have outstanding refactoring features almost
baked into the environment -- because there is complete visibility of
all of the code in a particular system/project, it's conceptually
trivial for the environment to offer all sorts of refactoring
functionality.
I suspect we may eventually see the same kind of functionality
available for Clojure. It's pretty early on in the language's
(public) development right now though, so tooling is very much in its
infancy.
That being said, to answer your question, no, Clojure doesn't
currently have any refactoring tools (or, to be precise, no Clojure
editing environments yet provide refactoring tools, including
Enclojure). That being said, I would offer these three points to
allay your concern, since you self-identify as generally preferring
static typing:
(1) Refactoring is generally less necessary when using a dynamic
language (like Python, Ruby, or yes, Clojure) than it is in a
statically-typed language. In the latter, refactoring is often
required in order to get code to where it needs to be in order to fit
into the object system so it can be utilized as necessary by other
code (this is where the push up/down, encapsulation, anonymous->inner
class refactorings are mostly coming from). Those sorts of concerns
almost never come up in dynamic languages (at least in my experience)
-- there are typically few restrictions being placed on the
accessibility of code, so it's up to each programmer to use her best
judgment and follow best practices, respect "private" labellings put
in place by library authors, etc. Beyond that, less code is required
to do things in Clojure than in Java certainly, and likely even Scala
(consider Rich Hickey's ants example, which bolts together a robustly-
concurrent UI simulation in ~300 lines!). Assuming that the value of
good refactoring tools goes up as your codebase gets larger, and the
inverse is true, then not having refactoring tools on day one might be
a reasonable tradeoff.
(2) When you do need to refactor something (in Clojure, or Python, or
Ruby, etc.), you generally need to piece through it one bit at a
time. The most common refactoring that you'll want to perform is a
simple renaming (since, as I said in (1), most other refactoring use-
cases are rarely if ever applicable). In this case, a good editor or
IDE environment that allows you to safely preview a find & replace
operation across an entire project is helpful and recommended. If you
think using a crude F&R to do a rename refactoring sounds like
potentially-dangerous drudgery, I'd absolutely agree. It's a lot more
work than in a statically-typed language, and in many dynamic
languages (like Python and Ruby) unit tests and `svn revert` are all
that keep you from oblivion. Clojure helps beyond that, though,
because...
(3) While Clojure is dynamic, it's also *compiled*. That means that
it will throw an exception if a symbol is not in scope where you are
using it, so if you perform a renaming "refactor" using an F&R
approach on a Clojure codebase, simply loading up all of the files in
that codebase will immediately reveal any serious errors. We have an
ant process that does this (and checks for any reflection warnings to
boot, so that we can ensure that we're adding type hints as
necessary), so we have a pretty solid safety net. This is a huge
advantage for Clojure compared to its other dynamic friends, which
generally happily read in code that reference nonexistent "symbols",
and don't throw an error until the app has been running for three
weeks, at which point the faulty code path is evaluated. (It's at
this point where the TDD folks will say to me, "You're Doing It
Wrong". :-)
I hope that seems like a balanced, albeit opinionated perspective.
Cheers,
- Chas