;; WARNING: Clojure's keyword and symbol functions allow you to create
;; values that cannot be printed then later read and recreate those same
;; values.
;; For most common symbols and keywords, they round-trip through pr
;; then read-string, as this example shows.
user=> (read-string (with-out-str (pr {:a 1, :b 2})))
{:a 1, :b 2}
;; But these values do not round-trip through the same steps:
user=> (def kw1 (keyword "foo bar"))
#'user/kw1
user=> kw1
:foo bar
user=> (def s2 (with-out-str (pr {kw1 1, :b 2})))
#'user/s2
user=> s2
"{:foo bar 1, :b 2}"
user=> (read-string s2)
RuntimeException Map literal must contain an even number of forms clojure.lang.Util.runtimeException (Util.java:221)
;; Similarly for a symbol like (symbol "a;b")
user=> (def sym1 (symbol "a;b"))
#'user/sym1
user=> sym1
a;b
user=> (def s3 (with-out-str (pr sym1)))
#'user/s3
user=> s3
"a;b"
user=> (read-string s3)
a
;; If you wish to transmit data that may contain such values, one suggestion
;; is to use the transit library: https://github.com/cognitect/transit-format
;; It is much faster and formally specified.