in-ns is one of the right ways.
The way which feels most "right" to me is to (require '[example.code :as ec]) and work in the user namespace at the REPL; that way my throwaway experimental state stays in user and ec/foo is convenient enough to me (and it makes it obvious where foo is supposed to come from). You can always say (require :reload-all 'example.code) (same works with use) to force recompilation.
Also, here's a function to remove (from the current namespace) all mappings pulled in from a given namespace with use:
(defn unuse [ns]
(doseq [[n v] (ns-refers *ns*)]
(if (= (.. v ns name) ns)
(ns-unmap *ns* n))))
On top of that you could build
(defn reuse [ns]
(unuse ns)
(remove-ns ns)
(use :reload-all ns))
and say (reuse 'example.code) to get something close to a fresh start with your namespace. (Note that 1.2 new features such as deftype & defrecord introduce some complexities... In particular, unuse has no effect on imported class -- this includes records and deftype-created types. :reload-all still causes the deftype et al. forms to be recompiled, but I remember hitting weird cases where this didn't seem to be enough... Possibly my error, possibly some arcane aspect of these features I haven't yet fully explored.)