Skip to content

Commit fc53b44

Browse files
committed
- incorporated suggested changes from @pesterhazy
1 parent f5a9a5a commit fc53b44

1 file changed

Lines changed: 95 additions & 43 deletions

File tree

content/guides/weird_characters.adoc

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ through http://briancarper.net/blog/449/[a bit of hackery].
3434

3535
If you se `#` *at the end* of a symbol, then it is used to automatically
3636
generate a new symbol. This is useful inside macros to keep macro specifics
37-
from leaking into the userspace. A regulare `let` will fail in a macro definition
37+
from leaking into the userspace. A regular `let` will fail in a macro definition
3838

3939
[source,clojure]
4040
----
@@ -68,8 +68,7 @@ Another place you'll see the `#` is in
6868
<<xref/../../reference/reader#tagged_literals,tagged literals>>
6969
Most commonly you'll see this use in https://github.com/edn-format/edn[EDN]
7070
(extensible data notation - a rich data fromat that can be used in Clojure)
71-
and in ClojureScript (`#js`). Search for `#inst`, `#uuid`, or `#js` for some
72-
more info.
71+
and in ClojureScript (`#js`). See <<xref/../weird_characters#tagged_literals,`#inst`, `#uuid`, or `#js`>> for more info.
7372

7473
* <<xref/../../reference/reader#tagged_literals,Clojure Documentation Reader>>
7574
* http://briancarper.net/blog/449/[Clojure Reader Macros]
@@ -115,11 +114,20 @@ See <<xref/../weird_characters#dispatch,(`#`)>> for additional details.
115114
user=> [1 2 3 #_ 4 5]
116115
[1 2 3 5]
117116
----
118-
The docs suggest that "The form following `#_` is completely skipped by the reader,
117+
Note that the space following `#_` is optional, so
118+
[source,clojure]
119+
----
120+
user=> [1 2 3 #_4 5]
121+
[1 2 3 5]
122+
----
123+
also works. Also note that the discard macro works for EDN
124+
125+
The docs suggest that "The form following `#_` is completely skipped by the reader
119126
(This is a more complete removal than the `comments` macro which yields `nil`).".
120127
This can prove useful for debugging situations or for multiline comments.
121128

122129
* <<xref/../../reference/reader#,Clojure Documentation - Reader>>
130+
* https://github.com/edn-format/edn#tagged-elements[EDN Tagged Elements]
123131

124132
== #" - Regular Expression macro
125133
// " for the pleasure of emacs.
@@ -134,7 +142,8 @@ user=> (re-matches #"^test$" "test")
134142
"test"
135143
----
136144

137-
This form is compiled at *read time* into a host-specific regex machinery.
145+
This form is compiled at *read time* into a host-specific regex machinery, but
146+
it is not available in EDN.
138147

139148
* <<xref/../../reference/other_functions#regex,Clojure Documentation: Regex Support>>
140149

@@ -147,8 +156,8 @@ following two snippets of code are similar:
147156

148157
[source,clojure]
149158
----
150-
; anonymous function takin a single argument and printing it
151-
(fn [line] (println line)) ;
159+
; anonymous function taking a single argument and printing it
160+
(fn [line] (println line))
152161
153162
; anonymous function takin a single argument and printing it - shorthand
154163
#(println %)
@@ -166,10 +175,12 @@ user=> (macroexpand `#(println %))
166175

167176
== #' - Var macro
168177

169-
`#'` is the var quote. It is the same as the `var` function:
178+
`#'` is the var quote which expands into the `var` function:
170179

171180
[source,clojure]
172181
----
182+
user=> (read-string "'foo")
183+
(var foo)
173184
user=> (def nine 9)
174185
#'user/nine
175186
user=> nine
@@ -180,39 +191,47 @@ user=> #'nine
180191
#'user/nine
181192
----
182193
When used it will attempt to return the referenced var. This is useful when
183-
you want to talk ab out the reference/declaration instead of teh value it represents.
184-
See the use of `meta` int the metadata (`^`) discussion.
194+
you want to talk about the reference/declaration instead of the value it represents.
195+
See the use of `meta` int the metadata (<<xref/../weird_characters#metadata,`^`>>) discussion.
196+
197+
Note that the var quote is not available in EDN.
185198

186199
* <<xref/../../reference/special_forms#var,Clojure Official Documentation: Special Forms>>
187200

201+
[[tagged_literals]]
188202
== #inst, #uuid, and #js etc. - tagged literals
189203

190-
Commonly found in EDN and ClojureScript this use of `#` is called the _tagged literal_.
191-
Look at this example:
204+
Commonly found in EDN and Clojure/ClojureScript this use of `#` is called
205+
the _tagged literal_. Look at this example:
192206
[source,clojure]
193207
----
194208
user=> (java.util.Date.)
195209
#inst "2014-05-19T19:12:37.925-00:00"
196210
----
197211

198-
When we create a new date it is represented as a tagged literal, or in this case,
199-
a tagged string. We can use Clojures `read-string` to read this back (or use it directly):
212+
When we print a date it is represented as a tagged literal, or in this case,
213+
a tagged string. We can use Clojure's `read-string` to read this back
214+
(or use it directly):
200215
[source,clojure]
201216
----
202217
user=> (type #inst "2014-05-19T19:12:37.925-00:00")
203218
java.util.Date
204219
(read-string "#inst \"2014-05-19T19:12:37.925-00:00\"")
205220
#inst "2014-05-19T19:12:37.925-00:00"
206221
user=> (type (read-string "#inst \"2014-05-19T19:12:37.925-00:00\""))
222+
;; this type is host-dependent.
207223
java.util.Date
208224
----
209225

210226
A tagged literal tells the reader how to parse the literal value. Other common
211-
uses include `#uuid` for generating UUIDs and in the ClojureScript world an
227+
uses include `#uuid` for expressing UUIDs and in the ClojureScript world an
212228
extremely common use of tagged literals is `#js` which can be used to convert
213229
ClojureScript data structures into JavaScript structures directly. Note that
214-
`#js` doesn't convert recursivly, so if you have a nested data-structure, use
215-
`cjs->js`.
230+
`#js` doesn't convert recursively, so if you have a nested data-structure, use
231+
https://cljs.github.io/api/cljs.core/js-GTclj[`cjs->js`].
232+
233+
Note that while `#inst` and `#uuid` are available in EDN, `#js` isn't.
234+
216235

217236
* https://github.com/edn-format/edn#tagged-elements[EDN Tagged Elements]
218237

@@ -249,7 +268,14 @@ you'd expect an external caller to pass them in.
249268
user=> (macroexpand `#(println % %1)) ; use both % and %1
250269
(fn* [arg1] (clojure.core/println arg1 arg1)) ; still only takes 1 argument
251270
----
252-
There is also `%&` which is the symbol for variadic arguments
271+
There is also `%&` which is the symbol for variadic arguments.
272+
[source,clojure]
273+
----
274+
user=> (macroexpand '#(println %&))
275+
(fn* [& rest__11#] (println rest__11#))
276+
----
277+
278+
Note that `%&` is not available in EDN.
253279

254280
== @ - Deref macro
255281

@@ -270,6 +296,8 @@ user=>
270296
be applied to other things such as `future` s, `delay` s, `promises` s etc. to
271297
force computation and potentially block.
272298

299+
Note that `@` is not available in EDN.
300+
273301
== ^ - Metadata
274302

275303
`^` is the metadata marker. Metadata is a map of values (with shorthand option)
@@ -278,15 +306,15 @@ for these forms and can b e used for documentation, compilation warnings,
278306
typehints, and other features.
279307
[source,clojure]
280308
----
281-
user=> (def ^{ :debug true } five 5) ; meta map with single boolean value
309+
user=> (def ^{:debug true} five 5) ; meta map with single boolean value
282310
#'user/five
283311
----
284312

285313
We can access the metadata by the `meta` function which should be executed
286314
against the declaration itself (rather than the returned value):
287315
[source,clojure]
288316
----
289-
user=> (def ^{ :debug true } five 5)
317+
user=> (def ^{:debug true} five 5)
290318
#'user/five
291319
user=> (meta #'five)
292320
{:ns #<Namespace user>, :name five, :column 1, :debug true, :line 1, :file "NO_SOURCE_PATH"}
@@ -312,7 +340,7 @@ user=> (meta #'five)
312340
----
313341
We can see in that example the `:tag` property is set.
314342

315-
You can also stak the shorthand notations:
343+
You can also stack the shorthand notations:
316344
[source,clojure]
317345
----
318346
user=> (def ^Integer ^:debug ^:private five 5)
@@ -321,6 +349,8 @@ user=> (meta #'five)
321349
{:ns #<Namespace user>, :name five, :column 1, :private true, :debug true, :line 1, :file "NO_SOURCE_PATH", :tag java.lang.Integer}
322350
----
323351

352+
Note that metadata is available in EDN, but bype hints are not.
353+
324354
* <<xref/../../reference/metadata#,Clojure Official Documentation>>
325355
* http://en.wikibooks.org/wiki/Learning_Clojure/Meta_Data[Learning Clojure: Meta Data]
326356

@@ -341,12 +371,14 @@ user=> (quote (1 2 3)) ; using the longer quote method
341371
user=>
342372
----
343373

374+
Note that ``` is available in EDN.
375+
344376
* <<xref/../../reference/special_forms#quote,Clojure Official Documentation>>
345377

346378
== ; - Comment
347379

348-
`;` is a comment. In fact it's a comment *macro* that takes all input from its
349-
starting point to the end of the line and ensures that the reader ignores it.
380+
`;` is a comment. It takes all input from its starting point to the end of the
381+
line and ensures that the reader ignores it.
350382
[source,clojure]
351383
----
352384
user=> (def x "x") ; this is a comment
@@ -375,7 +407,7 @@ A neat thing about keywords is that they alsoe implement `IFn` and can act as
375407
functions for extracting values from maps which is very nice:
376408
[source,clojure]
377409
----
378-
user=> (def my-map { :one 1 :two 2 })
410+
user=> (def my-map {:one 1 :two 2})
379411
#'user/my-map
380412
user=> (:one my-map) ; get the value for :one by invoking it as function
381413
1
@@ -400,18 +432,20 @@ user=> ::my-keyword
400432
user=> (= ::my-keyword :my-keyword)
401433
false
402434
----
403-
This is useful when creating macros. If you want to ensure a macro, that calls
404-
another function in the macro namespace, correctly expands to call the function,
435+
This is useful when creating macros. If you want to ensure that a macro that calls
436+
another function in the macro namespace correctly expands to call the function,
405437
you could use `::my-function` to refer to the fully qualified name.
406438

439+
Note that `::` is not available in EDN
440+
407441
* <<xref/../../reference/reader#,Reader>>
408442

409443
== / - Namespace separator
410444

411-
`/` can be the division function `/`, but can also act as a separator in a
412-
symbol name to break apart the symbol name and the namespace it resides in, eg
413-
`my-namespace/utils`. this allows symbols to be fully qualified to prevent
414-
collitsions or spread.
445+
`/` can be the division function `clojure.core//`, but can also act as a
446+
separator in a symbol name to break apart the symbol name and the namespace it
447+
resides in, e.g. `my-namespace/utils`. This allows symbols to be fully qualified
448+
to prevent collisions.
415449

416450
* <<xref/../../reference/reader#,Reader>>
417451

@@ -474,6 +508,7 @@ threading macros that perform variations on the same theme (`cond->`, `some->`,
474508
https://github.com/rplevy/swiss-arrows[swiss arrows], dedicated to the threading
475509
macros.
476510

511+
* <<xref/../../reference/threading_macros#,Official Clojure Documentation>>
477512
* http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/[Understanding the Clojure +->+ macro]
478513

479514
[[unqote]]
@@ -515,7 +550,7 @@ which takes a seq and expands it out as arguments to the applied function.
515550
----
516551
user=> (def three-and-four (list 3 4))
517552
#'user/three-and-four
518-
user=> `(1 ~three-and-four) ; treates as a single statement produces a nested list
553+
user=> `(1 ~three-and-four) ; treats as a single statement produces a nested list
519554
(1 (3 4))
520555
user=> `(1 ~@three-and-four) ; expand out as seperate statements
521556
(1 3 4)
@@ -549,7 +584,7 @@ ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval8
549584
user=> `(1 2 3)
550585
(1 2 3)
551586
----
552-
You'll see this most often in teh context of macros. We can write one now:
587+
You'll see this most often in the context of macros. We can write one now:
553588
[source,clojure]
554589
----
555590
user=> (defmacro debug [body]
@@ -579,8 +614,8 @@ where you are in the program. The earmuffs act as a warning that "here be dragon
579614
and to never assume the state of the var. Remember, this is a *convention*, not a
580615
*rule*.
581616

582-
Core Clojure exampels are `\*out*` and `\*in*` which represent the standard in and
583-
out writers for Clojure.
617+
Core Clojure exampels include `\*out*` and `\*in*` which represent the standard in
618+
and out writers for Clojure.
584619

585620
* http://stackoverflow.com/questions/1986961/how-is-the-var-name-naming-convention-used-in-clojure[How is the var-name naming-convention used in clojure?]
586621
* http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/\*out*[Clojure API Docs]
@@ -654,9 +689,8 @@ This is simply a recommended *convension*, not a *requirement*.
654689

655690
== <symbol>! - Unsafe Operations
656691

657-
The Clojure style guide has this to say
692+
https://github.com/bbatsov/clojure-style-guide#changing-state-fns-with-exclamation-mark[The Clojure style guide has this to say]:
658693

659-
[]
660694
====
661695
The names of functions/macros that are not safe in STM transactions
662696
should end with an exclamation mark (e.g `reset!`).
@@ -676,12 +710,14 @@ user=> @my-stateful-thing
676710

677711
This is simply a recommended *convention* and not a *requirement*
678712

713+
Note that the exclamation mark is often pronounced as bang.
714+
679715
* https://github.com/bbatsov/clojure-style-guide#naming[Clojure Style Guide]
680716

681717
== _ - Irrelevant var
682718

683-
When you see this used as function arguments or similar, it is a common
684-
naming convention for vars or arguments you are not interested in using.
719+
When you see the underscore character used as function arguments or similar,
720+
it is a common naming convention for vars or arguments you are not interested in using.
685721
That is you don't intend to use them, so you aren't really interested in
686722
thinking of a useful name for them.
687723

@@ -708,7 +744,7 @@ last argument - the new value of the atom.
708744
Reader conditionals are designed to allow
709745
different dialects of Clojure to share common code. The standard reader
710746
conditional behaves similarly to a traditional `cond`. The syntax for usage
711-
is `#?` and looks like:
747+
is `#?` and looks like this:
712748
[source,clojure]
713749
----
714750
#?(:clj (Clojure expression)
@@ -740,7 +776,7 @@ as this:
740776

741777
Map namespace syntax was added in Clojure 1.9 and is used to specify a default
742778
namespace context for keys in the map using a `#:ns` prefix, where _ns_ is the
743-
name of a namespace and the prefix precedes teh opening brace `{` of the map.
779+
name of a namespace and the prefix precedes the opening brace `{` of the map.
744780

745781
For example, the following map literal with namespace syntax:
746782
[source,clojure]
@@ -764,16 +800,18 @@ is read as:
764800
== +#::+ Autoresolving Namespace Syntax
765801

766802
`#::` can be used to auto-resolve namespaces with the same semantics as
767-
<<xref/../weird_characters#autoresolved_keys,autoresolved keywords.>>.
803+
<<xref/../weird_characters#autoresolved_keys,autoresolved keywords>>.
768804

769805
* <<xref/../../reference/reader#map_namespace_syntax,Reader>>
770806

771807
== #= Reader eval
772808

773-
`#=` allows the reader to evaluate the following form.
774-
Examples
809+
`#=` allows the reader to evaluate an arbitrary form during read time:
810+
775811
[source,clojure]
776812
----
813+
user=> (read-string "#=(+ 3 4)")
814+
;;=> 7
777815
#=123
778816
;;=> 123
779817
@@ -785,6 +823,20 @@ Examples
785823
;;=> 1
786824
----
787825

826+
Note that the read-time evaluation can also cause side-effects:
827+
[source,clojure]
828+
----
829+
user=> (read-string "#=(println :foo)")
830+
:foo
831+
nil
832+
----
833+
Consequently, `read-string` is not safe to call with unverified user input.
834+
For a safe alternative, see https://clojure.github.io/clojure/clojure.edn-api.html#clojure.edn/read-string[`clojure.edn/read-string`].
835+
836+
Note that `#=` is not an officially supported feature of the reader, so you
837+
shouldn't rely on its presence in future versions of Clojure.
838+
839+
788840
[]
789841
====
790842
Many thanks to everyone who has contributed ideas and [the copious amounts of]

0 commit comments

Comments
 (0)