Clojure: Variable Name Conventions
Here's list of magic characters as prefix or postfix to clojure variable and function names.
- 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/*1clojure.core/*2clojure.core/*3clojure.core/*e
x?-
by convention, names ending with question mark means it's a function that returns either
trueorfalse. 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
:keyin 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.
- 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
\uNNNNas 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.%1means first argument.%2means 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.%1means first argument.%2means 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.cljat 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/gensymclojure.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,
`xis the same as'x.
- For Symbols, syntax-quote resolves the symbol in the current context, yielding a fully-qualified symbol (i.e.
namespace/nameorfully.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.
#'xis 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
sigils war, magic chars in variable name
- Variable Naming: English Words Considered Harmful
- Parameter names start with phi φ, variable names start with xi ξ
- The Sigil War, Syntactic Indicator for Types of Function and Variable (2016)
- Elisp: DOLLAR SIGN $ and AT SIGN @ in Variable Name
- Jargon: Predicate in Programing Languages (2014)
- Syntactic Meaning of Variable (2018)
- Perl: Variable Name Prefix (aka Sigil)
- Ruby: Variable Name Conventions
- PowerShell: Automatic Variables
- Clojure: Variable Name Conventions