Skip to content

Commit 7dd399e

Browse files
authored
Clojurescript Reader & data_readers.cljc (#391)
* guide for Clojurescript Reader, mostly focusing on the differences from Clojure tagged literals. * clarify clj reader fns * add a note about automatic requires done by cljs compiler * rework guide for 1.11.51 release * clarify when macro-style readers are used
1 parent c962c09 commit 7dd399e

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

content/about/differences.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ See <<xref/../../guides/quick-start#,Quick Start>>
8282
** Because there is no character type in ClojureScript, ``\`` produces a single-character string.
8383
* `read`
8484
** The `read` and `read-string` functions are located in the `cljs.reader` namespace
85+
* Tagged Literals
86+
** The same as https://clojure.org/reference/reader[Clojure Tagged Literals], except that reader functions used at the compilation stage are similar to a Clojurescript macros, in that they
87+
should return a Clojurescript code form (or a literal such as a string or number).
88+
** The Clojure compiler does not automatically require reader functions referred to in data_readers.clj/c,
89+
but the Clojurescript compiler does.
90+
** see reader.adoc[The Reader] for more details
8591

8692
== The REPL and main
8793

content/guides/reader.adoc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
= The Reader
2+
Henry Widd
3+
2022-05-14
4+
:type: guides
5+
:toc: macro
6+
:icons: font
7+
8+
ifdef::env-github,env-browser[:outfilesuffix: .adoc]
9+
10+
toc::[]
11+
12+
The behaviour of Clojurescript's reader is mostly the same as the https://clojure.org/reference/reader[Clojure Reader]
13+
but with notable differences with respect to tagged literals.
14+
15+
[[tagged_literals]]
16+
== Tagged Literals
17+
18+
Tagged Literals allow users to extend the reader. See the Clojure https://Clojure.org/reference/reader#tagged_literals[Reader guide]
19+
on tagged literals for an introduction.
20+
21+
== Reader functions
22+
23+
Imagine we have a custom tagged literal `#foo/bar`. We need to define reader functions for the contexts where we
24+
want to read it, which will be one or both of:
25+
26+
* Clojurescript source code or REPL input
27+
* in a JS runtime when reading (EDN) data
28+
29+
=== Clojurescript compilation
30+
31+
In this situation Reader functions execute in Clojure and should return either a form which represents valid Clojurescript (similar to a Clojurescript macro) or
32+
a literal such as a string or number.
33+
34+
[source,Clojure]
35+
----
36+
(defn my-cljs-targeting-reader-fn [form]
37+
`(.foo ~form))
38+
----
39+
40+
This contrasts with Clojure reader functions, which execute like a normal function.
41+
42+
[source,Clojure]
43+
----
44+
(defn my-clj-targeting-reader-fn [form]
45+
(.foo form))
46+
47+
----
48+
49+
In order to read custom tagged literals in Clojurescript source, namespaced symbols are associated with reader
50+
functions in a data_readers.cljc file as described in the Clojure https://Clojure.org/reference/reader#tagged_literals[Reader guide]. If the same tagged literal is to be used for both Clojure and Clojurescript, https://clojure.org/reference/reader#_reader_conditionals[reader conditionals] may be used in data_readers.cljc if the reader functions
51+
will be different for targeting Clojure vs Clojurescript.
52+
53+
=== Reading data
54+
55+
When using the EDN reader, reader functions are just regular Clojurescript functions (meaning not macro-like as when reading source).
56+
57+
[source,Clojure]
58+
----
59+
(def custom-tag-map {'foo/bar (fn [x] (.foo x))})
60+
61+
62+
(cljs.edn/read-string
63+
{:readers custom-tag-map}
64+
"#foo/bar \"abc\"")
65+
----
66+
67+
An alternative to `cljs.edn/read-string` is `cljs.reader/read-string`. This just calls `cljs.edn/read-string`, but note
68+
that the default tag mapping includes mappings read from data_readers.cljc. For the following to work, data_readers.cljc
69+
must contain and entry with key `'foo/bar` and a value that resolves to a regular Clojurescript function.
70+
71+
[source,Clojure]
72+
----
73+
(cljs.reader/read-string "#foo/bar \"abc\"")
74+
----
75+

0 commit comments

Comments
 (0)