Syntax

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.


Literals

number literal - syntax

ClojureScript numbers are the same as JavaScript numbers (floats). Available formats:

  • decimal 123 1.23
  • exponent 12e3 1.2e3 1.2e-3
  • hexadecimal 0x123
  • octal 0123
  • binary 2r0110
  • arbitrary NrXXX where (<= 2 N 36) and X is in [0-9,A-Z]

"" string - syntax

A string of characters.

  • "..."
  • "single line string"
"multi
line
string"

#"" regex - syntax

Regular expressions compile to native JavaScript regular expressions.

  • #"..." => js /.../
  • #"(?i)..." => js /.../i (case-insensitive)
  • #"(?m)..." => js /.../m (multi-line)

\ character - syntax

A single character string.

  • \c => "c"
  • \A => "A"
  • \newline => "\n"
  • \u00a1 => "¡"
  • \o256 => "®"

: keyword - syntax

A keyword starts with a colon and evaluates to itself. It can include an optional namespace.

  • :bar
  • :foo/bar

:: keyword - syntax

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

symbol literal - syntax

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.

Special Symbols

true - special symbol

The boolean literal for true.


false - special symbol

The boolean literal for false.


nil - special symbol

nil is a representation of nothing. Its underlying representation is JavaScript's null, and is equal to JavaScript's undefined when compared.


NaN - special symbol

Floating point representation of NaN (not a number), an undefined or unrepresentable number.


Infinity - special symbol

Floating point representation of Infinity.

  • Infinity = +Infinity
  • -Infinity

Collections

[] vector - syntax

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.


() list - syntax

A list is interpreted as a call when evaluated.

  • (...)
  • (foo 1 2 3) - call foo with arguments 1, 2, 3

{} map - syntax

A 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)

#{} set - syntax

An unordered set of values. Values must be unique.

  • #{...}
  • #{1 2 3}

#:{} namespaced map - syntax

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}

#::{} namespaced map - syntax

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}

Commenting

; comment - syntax

A single line comment.

  • ; this is a comment
  • ;; two semicolons is also common

#! shebang - syntax

ClojureScript allows shebang lines simply by making #! equivalent to ; comment.

  • #!/usr/bin/env planck - use Planck to execute this file

#_ ignore - syntax

Ignore 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))

Function

#() function - syntax

Shorthand for creating an anonymous function. Use % arg to refer to the arguments.

  • #(...) => (fn [args] (...))

% arg - syntax

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 args

& rest - special character

A 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 sequences

Destructuring

destructure [] - binding

Shorthand 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 value

destructure {} - binding

Shorthand 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 value

Conventions

? predicate - convention

A naming convention for functions returning true or false (unenforced). Examples:


! impure - convention

A naming convention sometimes applied to functions that perform mutations. Examples:


*earmuffs* - convention

A naming convention for dynamic vars (unenforced).

  • (def ^:dynamic *foo* 1)

_ unused - convention

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 sequence

whitespace - special character

Any 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.


, comma - special character

Commas are ignored and can be used for assisting readability.

  • [1, 2, 3] => [1 2 3]
  • {:a 1, :b 2} => {:a 1 :b 2}

Symbol Resolution

. dot - special character

Dots can be used inside symbols for JS interop.

  • (.foo bar) => bar.foo()
  • (.-foo bar) => bar.foo
  • (foo.) => new foo()

The following are also supported (though not valid in Clojure)

  • foo.bar.baz => foo.bar.baz
  • (foo.bar.baz) => foo.bar.baz()

/ namespace slash - special character

The left side of / in a keyword or symbol is a namespace.

  • foo/bar
  • :foo/bar

js/ namespace - special namespace

Use a JavaScript variable.

  • js/document - the global document object
  • js/console.log - the global console log function

Math/ namespace - special namespace

A special namespace for direct access to the native JavaScript Math library.

  • Math/PI => js/Math.PI

Tagged Literals

# tagged literal - syntax

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 literal - tagged literal

Create a JavaScript object or array.

  • #js [...] - JS Array
  • #js {...} - JS Object (with stringified keys)

#inst literal - tagged literal

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 offset

#uuid literal - tagged literal

A 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 example

#queue literal - tagged literal

A queue is defined by placing #queue before a vector.

  • #queue [...]

Quoting

' quote - syntax

Return the following form without evaluation, especially for symbols and lists.

  • 'foo => foo
  • '(foo) => (foo)

` syntax quote - syntax

A template facility for easier code generation inside macros. Like ' quote, but with more features to help resolve symbols and interpolate values.

  • `(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 # unique

~ unquote - syntax

Inserts an evaluated form inside of a ` syntax quote template.

  • `(foo ~x) => (cljs.user/foo 123) (if x is 123)

~@ unquote splicing - syntax

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])

# auto-gensym - special character

Shorthand for generating unique symbols inside a ` syntax quote template.

  • foo# => foo__135__auto__

Vars

^ meta - syntax

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 <value of foo>}

#' var - syntax

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)

@ deref - syntax

Get the value that a reference is currently referring to. A "reference" can be a atom, delay, or var.

  • @foo - returns value at reference foo

Reader Conditionals

#? reader conditional - syntax

Use a different expression depending on the compiler (e.g. Clojure vs ClojureScript).

  • #?(:clj ... :cljs ...)

#?@ reader conditional splicing - syntax

Like #? reader conditional, except the result is spliced (i.e. [a b] => a b)

  • #?@(:clj [...] :cljs [...])

Misc

# dispatch - syntax

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

#<> unreadable - syntax

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.


#= eval - syntax

The ability to evaluate forms at reader-time should be ignored in ClojureScript.

  • #=...