Clojure Sigils (Magic Characters)
Here's list of clojure's special looking syntax.
- Some are macro characters, e.g.
'
@
^
#
. - Some are simply Clojure syntax, e.g. •
;comment
•[… & …]
•a/b
•:a
•::a
•a#
•a$b
, etc. - Some of them are just function names, e.g. •
+
•=
•>
•*
, or macro names, e.g.->
•->>
, etc.
Following are details.
x/y
-
slash used in identifier is a namespace separator. 〔see Clojure: Namespace〕
*x*
-
by convention, names starting and ending with asterisk usually means it's a builtin variable. Examples:
clojure.core/*clojure-version*
clojure.core/*command-line-args*
clojure.core/*compile-files*
clojure.core/*compile-path*
clojure.core/*compiler-options*
clojure.core/*err*
clojure.core/*file*
clojure.core/*flush-on-newline*
clojure.core/*in*
clojure.core/*ns*
clojure.core/*out*
clojure.core/*print-length*
*x
-
by convention, names starting with asterisk but not ending with asterisk usually means it's a builtin variable, whose value will change often. examples:
clojure.core/*1
clojure.core/*2
clojure.core/*3
clojure.core/*e
x?
-
by convention, names ending with question mark means it's a function that returns either
true
orfalse
. Example:clojure.core/empty?
clojure.core/even?
x!
-
by convention, names ending with exclaimation mark means it's a function that modify a variable in-place. Example:
clojure.core/assoc!
x-
-
by convention, names ending with hypen means it creates a private function. Example:
clojure.core/defn-
clojure.test/deftest-
:x
-
Clojure data type “clojure.lang.keyword”.
Clojure “keyword” is 2 things:
- Keyword acts as inert identifier when used as keys in Clojure map data type. e.g.
{:joe 8, :john 9}
. - Keyword is also function that retrieve the key of the same name from a map data type. e.g.
(:a {:a 8, :b 9})
returns8
- Keyword acts as inert identifier when used as keys in Clojure map data type. e.g.
::x
-
Return a keyword datatype but with the name x expanded to include namespace.
This is usually used just like
:key
in a map data type, but when you want fully qualified names to avoid key clashes when 2 maps are merged from different libraries.〔Did you know about ::keywords? By Meikel Brandmeyer. At http://kotka.de/blog/2010/05/Did_you_know_III.html〕
(def x 3) :x ; :x ::x ; :user/x
\chars
-
- character escape. e.g. {
\a
,\newline
,\space
,\tab
,\formfeed
,\backspace
,\return
}. - Unicode characters are represented with
\uNNNN
as in Java. - Octals are represented with
\oNNN
.
- character escape. e.g. {
_
-
- No special meaning. Lowline character is a allowed char for symbol.
- By convention, often used in function parameter as a name of a variable that is not used in function body.
e.g.
(fn [x [_ y]] (+ x y))
.This is often used when input (argument) is of a particular structure, thus the function parameters needs to match the shape, but only part of the value of the input is used in function body. 〔see Clojure: Binding Forms, Destructuring〕
Function Parameter
[… & …]
-
for declaring optional parameters in function definition. e.g.
(defn my-length [& xx] (count xx))
.clojure.core/&
〔see Clojure: Functions〕
%
-
- used inside
#(…)
to stand for function parameters. %
means first argument.%1
means first argument.%2
means second argument.- e.g.
#(+ %1 %2)
is equivalent to(fn [x y] (+ x y))
- 〔see Clojure: Functions〕
- used inside
Function Chaining (Piping)
(-> …)
-
macro for function chaining. Clojure calls it “threading”.
clojure.core/-&
(-> x f)
-
equivalent to
(f x)
(-> x f g)
-
equivalent to
(g (f x))
(->> …)
-
like unix pipe, but pass arg into the last argument position of function.
clojure.core/->>
〔see Clojure: Function Chaining〕
Dot Special Form, for Calling Java, outerClass$innerClass
(. …)
-
For calling Java's instance methods/field.
-
(. objectName methodName args)
-
is Java's
objectName.methodName(args)
clojure.core/.
(.x a b …)
-
- equivalent to
(. a x b …)
- (Note: the dot appear before a identifier, with no space in between.)
- equivalent to
(x. …)
-
- equivalent to
(new x …)
. - e.g.
(java.util.Date.)
is equivalent to(new java.util.Date)
clojure.core/new
- equivalent to
(.. o m1 m2)
-
- linear syntax for method chaining of Java methods.
- e.g.
(.. System (getProperties) (get "os.name"))
is equivalent to(. (. System (getProperties)) (get "os.name"))
clojure.core/..
x$y
-
Access Java inner class. It means this EnclosingClass$NestedClass.
〔see Clojure: Call Java Method〕
Metadata
^{…} obj
-
same as
(with-meta obj {…})
^:x obj
-
same as
(with-meta obj {:x true})
^"…" obj
-
same as
(with-meta obj {:tag "…"})
#^map form
-
add metadata map to form.
〔see Clojure: Metadata〕
others
@x
-
- equivalent to
(deref x)
. - This is known as “deference”
clojure.core/deref
- equivalent to
#char
-
- “macro dispatch”.
- Whenever this char appears, it has special interpretation of adjacent syntax.
- The number sign char # causes Clojure “reader” to interpret adjacent syntax differently than normal.
- The character char following
#
is a “key” to a “reader table” that determines how it is to be interpreted.
#{…}
-
- syntax for the datatype “set” (a collection of things).
- 〔see Clojure: Collections (List, Vector, Set, Map, etc), Sequence〕
#"regex"
-
- Creates a regex object.
- The resulting object is of type
java.util.regex.Pattern
. - 〔see Clojure: regex〕
#(…)
-
- equivalent to function definition by
fn
. - Inside the parenthesis of
#(…)
,%
means first argument.%1
means first argument.%2
means second argument. - e.g.
#(+ %1 %2)
is equivalent to(fn [x y] (+ x y))
. %&
means rest arg.- The
#(…)
form cannot be nested. - 〔see Clojure: Functions〕
- equivalent to function definition by
#_…
-
- Ignore next form.
- The form following
#_
is completely skipped by the “reader”.
[4 #_5 6] ; [4 6] [4 #_ 5 6] ; [4 6] [4 #_ [7 8] 6] ; [4 6] [4 #_ youdontknow 6] ; [4 6] [4 #_ youdontknow# 6] ; [4 6] [4 #_ (screwed not) 6] ; [4 6] [4 #_ not) 6] ; runtime error [4 #_ (not)) 6] ; runtime error
#x form
-
- when number sign appear before a identifier thing such as variable name, it's known as “tagged literal”.
- Clojure will automatically call a function named x on form.
- There must be a file named named
data_readers.clj
at the root of the classpath. - This file must contain a clojure map data type, that is, of the form
{pair1 pair2 etc}
, where the key of the pair is a tag name, same as#x
, and value is full name of a Clojure function.
By default, clojure predefines some of the tagged literal. See https://github.com/edn-format/edn https://clojure.github.io/clojure/clojure.edn-api.html
x#
-
- when number sign appear after identifier, it causes Clojure to generate a new unique name internally, to avoid clash with other identifiers.
- This is usually used inside defmacro.
clojure.core/gensym
clojure.core/defmacro
Macros, Forms, Holding Evaluation
'form
-
- equivalent to
(quote form)
. - It returns the un-evaluated form of form.
clojure.core/quote
'(+ 1 2) ; returns (+ 1 2)
- equivalent to
`(…)
-
- Syntax-quote.
- This will hold a expression in a un-evaluated form.
`(+ 1 2) ; returns (clojure.core/+ 1 2)
`(…)
-
Similar to
'(…)
, with the following exceptions:- The symbols inside has their namespace attached. For example,
`(list 3 4)
becomes`(clojure.core/list 3 4)
- you can use
~
and~@
to evaluate parts of the form inside a`(…)
(def x 3) '(list x) ;; (list x) `(list x) ;; (clojure.core/list xah-clojure-play.core/x)
(def x 3) '(list ~x) ;; (list (clojure.core/unquote x)) `(list ~x) ;; (clojure.core/list 3)
- The symbols inside has their namespace attached. For example,
~form
-
- syntax unquote.
- Used inside syntax quote
`(…)
, will evaluate the form form
~@form
-
- unquote-splicing.
- Used inside syntax quote
`(…)
, will evaluate the form form and remove its outer parenthesis.
~@
-
- Unquote-splicing.
- For all forms other than Symbols, Lists, Vectors, Sets and Maps,
`x
is the same as'x
.
- For Symbols, syntax-quote resolves the symbol in the current context, yielding a fully-qualified symbol (i.e.
namespace/name
orfully.qualified.Classname
). - If a symbol is non-namespace-qualified and ends with #, it is resolved to a generated symbol with the same name to which _ and a unique id have been appended.
- e.g.
x#
resolves tox_123
. - All references to that symbol within a syntax-quoted expression resolve to the same generated symbol.
- For Lists/Vectors/Sets/Maps, syntax-quote establishes a template of the corresponding data structure.
- Within the template, unqualified forms behave as if recursively syntax-quoted, but forms can be exempted from such recursive quoting by qualifying them with unquote or unquote-splicing, in which case they will be treated as expressions and be replaced in the template by their value, or sequence of values, respectively.
#'x
-
Known as “var quote”. e.g.
#'x
is equivalent to(var x)
.clojure.core/var
(def x 3) (var x) ; returns #'user/x
;
-
line comment.
,
-
Comma is an optional separator, similar to space. Usually used in a map data type.
e.g.
{:x 8, :y 9}
is equivalent to{:x 8 :y 9}
is also equivalent to{:x, 8, :y, 9}
.[3,4]
is equivalent to[3 4]
.