This is an index of ClojureScript's syntax forms, including syntax literals, naming conventions, and other syntax patterns. We hope that you can have any question about syntax answered by referencing its appearance in this index.
ClojureScript numbers are the same as JavaScript numbers (floats). Available formats:
123
1.23
12e3
1.2e3
1.2e-3
0x123
0123
2r0110
NrXXX
where (<= 2 N 36)
and X
is in [0-9,A-Z]
A string of characters.
"..."
"single line string"
"multi
line
string"
Regular expressions compile to native JavaScript regular expressions.
#"..."
=> js /.../
#"(?i)..."
=> js /.../i
(case-insensitive)#"(?m)..."
=> js /.../m
(multi-line)A single character string.
\c
=> "c"
\A
=> "A"
\newline
=> "\n"
\u00a1
=> "¡"
\o256
=> "®"
A keyword starts with a colon and evaluates to itself. It can include an optional namespace.
:bar
:foo/bar
Shorthand for specifying namespaced keywords. Allows you to use an aliased namespace or to have the current one auto-inserted if not specified.
::foo/bar
=> :aliased-ns/bar
::bar
=> :current-ns/bar
A symbol is used as a name for a var. When evaluated, its result will be the value bound to the var.
bar
- evaluates to the value bound to bar
foo/bar
- evaluates to the value bound to a var outside the current namespace.
The namespace foo
can be an aliased or literal namespace.nil
is a representation of nothing. Its underlying representation is
JavaScript's null
, and is equal to JavaScript's undefined
when compared.
Floating point representation of NaN
(not a number), an undefined or
unrepresentable number.
Floating point representation of Negative Infinity -∞
.
A vector is the most commonly used form for creating literal sequences.
[...]
[1 2 3]
Vectors also serve an important language role to prevent you from interpreting
sequences as function calls. Whether it's for literal data or for binding forms
inside let
and fn
, vectors provide an
important syntax cue not found in other Lisps.
A list is interpreted as a call when evaluated.
(...)
(foo 1 2 3)
- call foo with arguments 1, 2, 3A map associates keys with values.
{...}
{:foo 1}
{:foo 1, :bar 2}
- comma is optional{[1 2] "foo"}
- keys and values can be any type (even collections)Provide a default namespace for keyword keys in a map.
#:a {1 nil, :b nil, :b/c nil, :_/d nil}
;;=> {1 nil, :a/b nil, :b/c nil, :d nil}
Provide a default namespace for keyword keys in a map, using an alias.
#:: {:a 1}
=> {:current-ns/a 1}
#::s {:a 1}
=> {:aliased-ns/a 1}
A single line comment.
; this is a comment
;; two semicolons is also common
ClojureScript allows shebang lines simply by making #!
equivalent to
; comment
.
#!/usr/bin/env planck
- use Planck to execute this fileIgnore the next well-formed expression.
[1 #_foo 2 3]
=> [1 2 3]
Also useful for commenting out a multi-line expression:
#_(defn foo [a b]
(+ a b))
Shorthand for creating an anonymous function. Use % arg
to refer
to the arguments.
#(...)
=> (fn [args] (...))
Use %
as the implicit argument to a #() function
, or use the following
if there are more than one:
%1
- first arg%2
- second arg%3
- third arg%&
- rest of the argsA concept shared between destructure []
and fn
for binding the rest of the values of a sequence to a name.
(fn [... & rest])
- for function arguments(let [[... & rest] ...])
- for sequencesShorthand for destructuring a sequence into multiple names. Allows you to use a
[...]
pattern instead of a usual name
in the following examples:
(defn [name])
-> (defn [[...]])
(let [name sequence])
-> (let [[...] sequence])
(for [name sequences])
-> (for [[...] sequences])
Quick pattern reference:
[...]
- names are bound by order (e.g. [a b]
)[... & name]
- name is bound to the rest of the values[:as name]
- name is bound to whole valueShorthand for destructuring a map into multiple names. Allows you to use a
{...}
pattern instead of a usual name
in the following examples:
(defn [name])
-> (defn [{...}])
(let [name map])
-> (let [{...} map])
(for [name maps])
-> (for [{...} maps])
Quick pattern reference:
{name lookup}
- name is bound using the lookup key{:keys [...]}
- names bound using keywords as lookup keys{:strs [...]}
- names bound using strings as lookup keys{:syms [...]}
- names bound using symbols as lookup keys{:as name}
- name is bound to whole valueA naming convention for dynamic vars (unenforced).
(def ^:dynamic *foo* 1)
When unused values require a name, it is common to use _
.
(fn [_ _ a]))
- ignore first two function arguments(let [[_ a _ b] ...])
- only bind names to 2nd and 4th values of a sequenceAny number of whitespace characters can be used between forms, but is optional around delimiters. Commas are considered whitespace. The following are equivalent:
#js [ 1 2 3 ]
#js [1 2 3]
#js [1, 2, 3]
#js[1 2 3]
#js[1,2,3]
Indentation is two-spaces, not tabs, by convention.
Commas are ignored and can be used for assisting readability.
[1, 2, 3]
=> [1 2 3]
{:a 1, :b 2}
=> {:a 1 :b 2}
Dots can be used inside symbols for JS interop.
(.foo bar)
=> bar.foo()
(.-foo bar)
=> bar.foo
(foo.)
=> new foo()
The left side of /
in a keyword or symbol is a namespace.
foo/bar
:foo/bar
Use a JavaScript variable.
js/document
- the global document objectjs/console.log
- the global console log functionAdd a type hint to a local binding name to prevent advanced compilation from munging property names on . dot
calls—
only if :infer-externs
is enabled.
^js
- short form^js/React.Element
- long form (purely for documentation, see details)A special namespace for direct access to the native JavaScript Math library.
Math/PI
=> js/Math.PI
Some frequently used value types are afforded a "tagged literal" syntax. It is similar to a constructor, but this special syntax makes it de/serializable and easier to read at the REPL.
Tagged literals start with a #
followed by a symbol and a literal:
#js [...]
- JavaScript array literal#js {...}
- JavaScript object literal#inst "..."
- JavaScript date literal#uuid "..."
- UUID literal#queue [...]
- queue literalCreate a JavaScript object or array.
#js [...]
- JS Array#js {...}
- JS Object (with stringified keys)Creates a JavaScript Date object using RFC-3339 formatted string.
#inst "yyyy-mm-dd"
- date#inst "yyyy-mm-ddThh:mm:ss"
- date and time#inst "yyyy-mm-ddThh:mm:ssZ"
- specify UTC#inst "yyyy-mm-ddThh:mm:ss-hh:mm"
- specify negative time zone offset#inst "yyyy-mm-ddThh:mm:ss+hh:mm"
- specify positive time zone offsetA universally unique identifier (UUID). Randomly generate one with random-uuid
.
#uuid "8-4-4-4-12"
- numbers represent the number of hex digits#uuid "97bda55b-6175-4c39-9e04-7c0205c709dc"
- actual exampleA queue is defined by placing #queue
before a vector.
#queue [...]
Return the following form without evaluation, especially for symbols and lists.
'foo
=> foo
'(foo)
=> (foo)
Expands to a clojure expression (at read time) which—when evaluated—produces the literal structure described by the template inside.
`(foo 123)
=> (cljs.user/foo 123)
- symbols become fully-qualified`(foo ~x)
=> (cljs.user/foo 123)
- interpolates the value of x
`(foo ~@y)
=> (cljs.user/foo 1 2 3)
- interpolates and splices the sequence of y
`(foo bar#)
=> (cljs.user/foo bar__20418__auto__)
- make symbols ending in #
uniqueInserts an evaluated form inside of a ``` syntax quote`` template.
`(foo ~x)
=> (cljs.user/foo 123)
(if x is 123)Like ~ unquote
, except the result is spliced (i.e. [a b]
=> a b
)
`(foo ~@x)
=> (cljs.user/foo a b)
(if x is [a b])Shorthand for generating unique symbols inside a ``` syntax quote`` template.
foo#
=> foo__135__auto__
Attach metadata to the following symbol or collection. Use a map to specify the metadata, or use shorthand:
^:foo
=> ^{:foo true}
^"foo"
=> ^{:tag "foo"}
^foo
=> ^{:tag foo}
To retrieve metadata like where a var was defined, we need to refer to the var itself. It is therefore helpful to be aware of the following subtle differences:
foo
=> returns value bound to foo'foo
=> returns the symbol foo (which is just a name)#'foo
=> returns the foo var itself (for retrieving metadata like where it was defined)Use a different expression depending on the compiler (e.g. Clojure vs ClojureScript).
#?(:clj ... :cljs ...)
Like #? reader conditional
, except the result is spliced (i.e. [a b]
=> a b
)
#?@(:clj [...] :cljs [...])
As a general pattern, syntax forms prefixed with #
are related to their
standalone forms:
relation | original | with # prefix |
---|---|---|
string-related | "" string |
#"" regex |
code-related | () list |
#() function |
lookup-related | {} map |
#{} set |
quote-related | ' quote |
#' var |
ignore-related | _ unused |
#_ ignore |
name-related | foo (symbol) |
#foo (tagged literal) |
conditional-related | ? predicate |
#? reader conditional |
The "symbolic values" ##Inf
, ##-Inf
, ##NaN
do
not follow this pattern, but the additional number sign in ##
serves as a
mnemonic for these special numerical values.
A proper definition for something that cannot be read.
#<...>
When certain values cannot be printed to a REPL using some literal syntax form,
it wraps a description of its value in a form defined as unreadable, #<>
. A
reader error will be thrown if this value is fed back into the REPL.
The ability to evaluate forms at reader-time should be ignored in ClojureScript.
#=...