0

Is it possible to customize cljs.reader/read-string to handle something like "#(f 123)"?

I tried this:

(cljs.reader/register-tag-parser! \( (fn [x] "test"))
(cljs.reader/read-string "#(f 123")

but get:

Could not find tag parser for (f in ("inst" "uuid" "queue" "js" "(")


Update:

after a little more digging I came across https://github.com/clojure/clojurescript/blob/6ff80dc2f309f961d2e363148b5c0da65ac320f9/src/test/cljs/cljs/pprint_test.cljs#L106 which confirms that this isn't currently possible:

(simple-tests pprint-reader-macro-test
  ;;I'm not sure this will work without significant work on cljs. Short story, cljs
  ;;reader only takes valid EDN, so #(* % %) won't work.
  ;;see http://stackoverflow.com/a/25712675/546321 for more details
  #_(with-pprint-dispatch code-dispatch
    (write (reader/read-string "(map #(first %) [[1 2 3] [4 5 6] [7]])")
           :stream nil))
  #_"(map #(first %) [[1 2 3] [4 5 6] [7]])"
estolua
  • 676
  • 4
  • 11

1 Answers1

0

The tag in tagged literals needs to be a qualified symbol (you can use a unqualified one, but it's discouraged). Symbols can't include parentheses (or other delimiters), because clojure(script) code needs to be a valid s-expression.

If you want to be hacky about it, though, from the error message you can see that the cljs reader thinks the tag is (f and not (. So, if you do

(cljs.reader/register-tag-parser! "(f" (fn [x] "test"))

it will work (in the current cljs, it'll probably break at some point).

madstap
  • 1,552
  • 10
  • 21
  • yeah sure, I'm basically asking how to extend what the `dispatch-macros` function does (https://github.com/clojure/clojurescript/blob/57819844b5a8da0464832f82426ac57ebdf2eaea/src/main/cljs/cljs/reader.cljs#L443) by way of the `*tag-table*` both of which are used disjunctively in `read-dispatch` so it seemed there might be a way. the expression inside the parens is variable so I can't hard-code `"(f"`. – estolua Jun 27 '17 at 09:57