Clojure Sigils (Magic Characters)

By Xah Lee. Date: . Last updated: .

Here's list of clojure's special looking syntax.

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 or false. 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}) returns 8
::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.
_
  • 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

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.)
(x. )
  • equivalent to (new x ).
  • e.g. (java.util.Date.) is equivalent to (new java.util.Date)
  • clojure.core/new
(Note: the dot appear after a identifier, with no space in between.)
(.. 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.

http://clojure.org/reference/java_interop

〔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
#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.
#{}
#"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
#_
  • 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)
`()
  • 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)
~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.
#'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].

Reference