If you wanted to serialize things to S-expressions, you could use print-dup:
(binding [*print-dup* true] (println [1 2 3]))
; prints [1 2 3]
(defrecord Foo [x])
; => user.Foo
(binding [*print-dup* true] (println (Foo. :foo)))
; prints #=(user.Foo/create {:x :foo})
Note that printing a structure which holds, say, ten references to a single vector followed by reading it back gives you a datastructure with ten separate (not identical?), though equivalent in terms of structure (=) vectors.
To use this in cases where there is no default implementation provided, implement the multimethod clojure.core/print-dup.
Also, a lot of things in Clojure 1.2 are java.io.Serializable:
(every? (partial instance? java.io.Serializable)
[{1 2} #{"asdf"} :foo 'foo (fn [] :foo)])
; => true
(defrecord Foo [])
(instance? java.io.Serializable (Foo.))
; => true
Note that you should avoid serializing runtime-created fns -- they are instances of one-off classes with weird names and you won't be able to deserialize them after restarting your JVM anyway. With AOT compilation, fns do get their own fixed classnames.
Update: As mentioned in a comment on the question, Serializable is best suited to short-term storage / transfer of data, whereas print-dup should be more robust as a long-term storage solution (working across many versions of the application, Clojure etc.). The reason is that print-dup doesn't in any way depend on the structure of the classes being serialized (so a vector print-dup'd today will still be readable when the vector implementation switches from Java to Clojure's deftype).