emacs.d/clones/lisp/clojure-doc.org/articles/tutorials/introduction/index.html

968 lines
63 KiB
HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8"/>
<title>Clojure Guides: Introduction to Clojure</title>
<meta name="description" content="This guide covers:">
<meta property="og:description" content="This guide covers:">
<meta property="og:url" content="https://clojure-doc.github.io/articles/tutorials/introduction/" />
<meta property="og:title" content="Introduction to Clojure" />
<meta property="og:type" content="article" />
<link rel="canonical" href="https://clojure-doc.github.io/articles/tutorials/introduction/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Alegreya:400italic,700italic,400,700" rel="stylesheet"
type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/default.min.css">
<link href="../../../css/screen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../../../index.html">Clojure Guides</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li ><a href="../../../index.html">Home</a></li>
<li><a href="https://github.com/clojure-doc/clojure-doc.github.io">Contribute</a></li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<div class="container">
<div class="row">
<div class="col-lg-9">
<div id="content">
<div id="custom-page">
<div id="page-header">
<h2>Introduction to Clojure</h2>
</div>
<p>This guide covers:</p><ul><li>Clojure language basics</li><li>expressions, identifiers (locals, vars)</li><li><code>let</code> forms</li><li>scalars</li><li>functions</li><li>basic data types</li><li>introduction to immutable data structures</li><li>overview of Clojure reference types (vars, atoms, agents, refs)</li><li>looping and recursion</li><li>basics of Clojure macros</li></ul><p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
Attribution 3.0 Unported License</a> (including images &amp;
stylesheets). The source is available <a href="https://github.com/clojure-doc/clojure-doc.github.io">on
Github</a>.</p><h2 id="overview">Overview</h2><p>This is a brief beginner's introduction to Clojure. If you haven't
already done so, have a look at the <a href="../getting_started/index.html">Getting
Started</a> tutorial. Before
continuing, make sure you've got Java and
<a href="http://leiningen.org">Leiningen</a> installed, and can create a new
project and run a REPL in it. The author expects you'll want to have a
REPL running while following this introduction so you can type
expressions into it as you go.</p><blockquote><p><strong>Note:</strong> In the code samples below, unless we're specifically
discussing the REPL, to reduce clutter we've usually omitted showing
the REPL prompt (ex. "<code>user=&gt;</code>" or "<code>my-proj.core=&gt;</code>").</p><p>Additionally: In Clojure, a semicolon begins a single-line comment,
and in this document we use "<code>; ⇒</code>" (for trailing comments) and
"<code>;; ⇒</code>" (for comments on their own line) to indicate what the
previous expression evaluates to.</p></blockquote><p>This introduction is a whirlwind tutorial of most of the basics of
Clojure. Its goal is to rapidly get you familiar with the core
areas of the language without wasting your time and also without getting
too bogged down in details or advanced topics (the various topics will
get more comprehensive coverage in the topic guides anyway).</p><p>As we said in the Getting Started tutorial, Clojure is a wonderfully
simple language, and you're going to love it.</p><h2 id="the-basics">The Basics</h2><p>Clojure is a general-purpose programming language, and a quite
practical one at that.</p><p>The syntax for Clojure is like Lisp and is very simple: code is made
up of expressions which are evaluated to some value. Here are some
examples of expressions:</p><pre><code class="clojure">5 ; ⇒ 5
"hi" ; ⇒ "hi"
[1 2 3] ; evaluates to the vector `[1 2 3]`
(+ 1 2) ; evaluates to the sum of 1 and 2
(if true "yes" "no") ; evaluates to the string "yes"
(println "hello!") ; evaluates to nil (but also prints "hello!")
</code></pre><p>Clojure supports a few extra bits of syntax which will be noted as we
encounter them.</p><p>Expressions can contain sub-expressions:</p><pre><code class="clojure">(+ 1
(* 2 3)
(/ 10 2)) ; ⇒ 1 + (2 * 3) + (10 / 2) = 12
</code></pre><p>Expressions in (various types of) brackets are often referred to as
"forms".</p><p>An expression in parentheses is usually treated as a function call,
but may also be a macro or special form (more about those in the
<a href="index.html#evaluation">Evaluation</a> section below).</p><p>Clojure is not whitespace-sensitive. Also, commas count as whitespace,
so you can omit them (for example, you can write a vector as <code>[1 2 3]</code>
instead of <code>[1, 2, 3]</code>).</p><p>Clojure code is block-structured and lexically scoped (though dynamic
scope is supported as well, if you really need it).</p><p>Clojure is a compiled language. The Clojure reader reads your source
code, then your code is compiled to JVM bytecode, and then it's run on
the JVM. The reader supports a few extra bits of syntactic sugar (for
example, a literal syntax for specifying regular expressions) that we
will cover as we go along.</p><p>Throughout this tutorial, we will liberally reference and lean on the
marvelous <a href="http://clojure.org/cheatsheet">Clojure Cheatsheet</a>. Aside
from being a great organizational aide, it also handily includes links
to the relevant <a href="http://clojuredocs.org/">Clojuredocs</a> pages where you
can find docs for and examples of the various Clojure functions.</p><p>In the REPL, at any time you can see the documentation for a given
function:</p><pre><code>(doc some-function)
</code></pre><p>and even the source code for it:</p><pre><code>(source some-function)
</code></pre><p>So, it will be of great use to you to have your REPL running so you
can try things out while following along.</p><h2 id="identifiers">Identifiers</h2><p>Identifiers are used to name things. For example, in</p><pre><code class="clojure">(def the-answer 42)
</code></pre><p>we've named something "the-answer" and given it the value 42.</p><p>In this document we'll mostly use lowercase letters, numbers, and
dashes to name things, although some other characters are allowed too,
such as <code>_&lt;&gt;!?*</code> (ex. <code>this-&gt;that</code>, <code>ready?</code>). We'll note more
examples of those cases later on as they come up.</p><h2 id="scalars">Scalars</h2><p>Clojure has support for the following kinds of scalar values:</p><pre><code class="clojure">nil
true, false
</code></pre><p><code>nil</code> is like Python's None, or Java's null. It's just another value.
Incidentally, there's no "undefined" value in Clojure --- if you try
to use a symbol which you haven't defined, then it's undefined and the
compiler will let you know about it.</p><p>As we go along, type those expressions into your REPL to see them
evaluated. These too:</p><pre><code class="clojure">1 ; integer
1N ; arbitrary-precision integer
1.2 ; float/double/decimal
1.2M ; arbitrary-precision decimal
1.2e4 ; scientific notation
1.2e4M ; sci notation of arbitrary-precision decimal
0x3a ; hex literal (58 in decimal)
1/3 ; Rational number, or "ratio".
\a ; The character "a".
"hi" ; A string.
</code></pre><p>Strings can span multiple lines --- just hit Enter and keep typing. If
you want to include a double-quote mark in a string, backslash-escape
it.</p><pre><code class="clojure">#"^foo\d?$" ; A regular expression.
:foo ; A keyword.
</code></pre><p>We'll have more to say about <a href="index.html#regular-expressions">regular
expressions</a> later on.</p><p>Keywords are just scalars that evaluate to themselves and are useful
where in other languages you might use little strings as identifiers
(for example, as the keys in a hashmap). More about keywords in the
next section (<a href="index.html#data-structures">Data Structures</a>).</p><pre><code class="clojure">'foo ; A symbol.
</code></pre><p>A <em>symbol</em> is an object that represents the <em>name</em> of something. The
single quote mark is there to keep Clojure from trying to figure out
to what the symbol refers (the quote isn't part of the identifier of
the symbol). When you want to represent the name of a thing --- rather
than the value to which it refers --- you use a symbol. Their utility
will become clearer later on when we briefly mention
<a href="index.html#macros-and-special-forms">Macros</a>.</p><blockquote><p><strong>Terminology:</strong> By "object" we just mean the internal thing that
Clojure uses to represent a value --- <em>not</em> "object" as in "object
oriented programming". Clojure is not an object oriented
language. Sure, you can easily access Java OOP objects from Clojure,
but that is outside the scope of this tutorial.</p><p>Also, the words "reference" and "refer" are used in Clojure in the
generic sense. A symbol refers to an object (it is not the object
itself). Clojure <em>also</em> happens to support something called
<em>reference types</em>. We'll cover them later on in the <a href="index.html#reference-types">Reference
Types</a> section.</p></blockquote><h2 id="data-structures">Data Structures</h2><p>Clojure comes out of the box with nice literal syntax for the various
core data structures:</p><pre><code class="clojure">[1 2 3] ; A vector (can access items by index).
[1 :two "three"] ; Put anything into them you like.
{:a 1 :b 2} ; A hashmap (or just "map", for short).
</code></pre><p>A hashmap is your typical hash/dictionary data structure. In the above
example, the keys are :a and :b, and the values are 1 and 2. One key-value
pair in a map is called an <em>entry</em>.</p><p>Although it's most common to use keywords (as shown above) for hashmap
keys, you can use any values you like for the keys as well as the
values.</p><pre><code class="clojure">#{:a :b :c} ; A set (unordered, and contains no duplicates).
'(1 2 3) ; A list (linked-list)
</code></pre><p>You generally don't use lists very often for typical sequential data
in your programs:</p><pre><code class="clojure">(def my-stuff '("shirt" "coat" "hat")) ; Works fine, but ...
(def my-stuff ["shirt" "coat" "hat"]) ; this is more typical usage.
</code></pre><p>Lists are most often used when treating code itself as just a bunch of
nested lists --- see <a href="index.html#macros-and-special-forms">Macros</a>.</p><p>BTW, don't mind that single-quote mark before the list's open paren;
it's just there to tell Clojure that this isn't a function call
(discussed in <a href="index.html#function-calls">Function Calls</a>, below), but rather, an actual
list.</p><blockquote><p>Note: In Clojure, we use the term "vector" rather than "array".
"Array" would refer to the native Java array, whereas "vector"
refers to the Clojure data structure.</p></blockquote><p>Nesting data structures works like you'd expect:</p><pre><code class="clojure">#{:a
[1 2 3]
{:foo 11 :bar 12}
#{"shirt" "coat" "hat"}}
</code></pre><p>We will see how to get at values inside nested data structures a little
later on.</p><h3 id="abstractions">Abstractions</h3><p>The data structures we just looked at (lists, vectors, maps, and sets)
are all concrete data types. The various Clojure functions for working
on them (which we will get to later on) actually aren't written to
work on the concrete types, but rather, are written to work on
abstract data types. The concrete data types are implementations of
the various abstract data types.</p><p>Some of the Clojure abstractions are:</p><ul><li>Collection (Lists, vectors, maps, and sets are all collections.)</li><li>Sequential (Lists and vectors are ordered collections.)</li><li>Associative (Hashmaps associate keys with values. Vectors associate numeric indices with values.)</li><li>Indexed (Vectors, for example, can be quickly indexed into.)</li></ul><p>In the docs for the various functions, you'll often see that they
take, for example, a "coll". This means that the particular function
will work on any of the collections.</p><blockquote><p>If you'd like to look under the covers and see what the type of
an object is, try <code>(type my-stuff)</code>.</p></blockquote><h2 id="evaluation">Evaluation</h2><p>So far you've been typing various literal values (expressions) into
the repl and Clojure has evaluated them and repeated their resulting
values back to you (printed them out in the repl):</p><pre><code class="clojure">user=&gt; "hi"
;; "hi"
user=&gt; :foo
;; :foo
user=&gt; [1 2 3]
;; [1 2 3]
</code></pre><p>Clojure evaluates the expressions you give it and tries to come up
with a resulting value. If the expression starts with an open paren,
Clojure treats it as either a macro, a <em>special form</em> (discussed
below) or else a function call.</p><h3 id="function-calls">Function Calls</h3><p>If the symbol right after the open paren names a function, Clojure
evaluates all of its function arguments first, then applies the
function to the values of those args:</p><pre><code class="clojure">(my-func arg1 arg2 arg3)
</code></pre><p>You can nest function calls as deep as tasteful discretion allows:</p><pre><code class="clojure">(my-func (my-func2 arg1
arg2)
(other-func arg-a
(foo-bar arg-x
arg-y
(+ arg-xx
arg-yy
arg-zz))
arg-b))
</code></pre><p>Note that your code will be easiest to read if you line up args to
functions vertically (as shown above). Your editor should take care of
this for you automatically.</p><p>By the way, there are no "operators" in Clojure per se; just function
names (symbols which refer to their corresponding functions). So, for
example, <code>+</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>=</code>, <code>*</code>, and <code>not=</code> are all just function
names.</p><h3 id="macros-and-special-forms">Macros and Special Forms</h3><p>If an expression starts with an open paren, Clojure first checks to
see if it's a macro or special form. These are forms which don't
follow the regular evaluation rule and get special treatment from the
Clojure compiler.</p><p>Macros are like functions which take as arguments regular Clojure code
(which is, after all, just a list of expressions and (usually nested)
other lists), and returns the code transformed / expanded in some
useful way.</p><p>You write macros to add new syntax to the Clojure language, and
usually it's only done when necessary, after you've already gotten as
far as you can with plain functions.</p><p>Macros are created using <code>defmacro</code>. Writing them involves
manipulating lists (Clojure code), just like you've already
seen. Though quoting and unquoting is used to control evaluation of
the code you're handling.</p><p>Macro calls in your code get expanded at compile-time, right before
the rest of your code is compiled. Certain Clojure built-ins like
<code>let</code>, <code>def</code>, and <code>if</code> are written as special forms which are
hard-coded into the compiler rather than macros, but this is an
implementation detail; the effect is the same.</p><p>This tutorial does not discuss macros further.</p><h3 id="quoting">Quoting</h3><p>If for whatever reason you'd rather Clojure <em>not</em> treat something like
<code>(+ 1 2 3)</code> as a function call, you can "quote" it like so:</p><pre><code class="klipse-clojure nohighlight">'(+ 1 2 3)
</code></pre><p>This causes Clojure to then regard it simply as a 4-element list;
the first element of which is the symbol for some function. Reasons
for wanting to do this will become clearer later on.</p><h2 id="let-and-locals">Let and Locals</h2><p>When you want some lexically-scoped named values to use in a section
of your code, you can use the <code>let</code> expression:</p><pre><code class="klipse-clojure nohighlight">(let [width 10
height 20
thickness 2]
(println "hello from inside the `let`.")
(* width
height
thickness))
</code></pre><p>The first thing inside the <code>let</code> is a binding vector. In it, you
specify the local names you'd like to make available inside the <code>let</code>,
along with their values.</p><blockquote><p><strong>Formatting note:</strong> Your readers might appreciate you vertically
lining up the values used in the binding vector, as we've done
above with 10, 20, and 2.</p></blockquote><p>These local names are symbols that refer directly to the values you
set them to.</p><p>You can re-set the symbols in the binding vector multiple times
(building it up into the value you need), if you find it useful:</p><pre><code class="klipse-clojure nohighlight">(let [x 2
x (* x x)
x (+ x 1)]
x)
</code></pre><p>The <code>let</code> expression itself evaluates to the last expression in its
body. You can put other things inside the <code>let</code> (like our <code>println</code>
expression, in the previous example), but the overall value of the
<code>let</code> is its last expression.</p><blockquote><p>Note that the <code>println</code> expression just evaluates to nil. We don't
use its value for anything --- we only care about its <em>side-effects</em>
(printing out to the console). More about
<a href="index.html#side-effects">Side-Effects</a> shortly.</p></blockquote><h2 id="namespaces">Namespaces</h2><p>Clojure uses <em>namespaces</em> to organize function names into groups
and to keep them from colliding with other function names.
All function names live in a namespace. All the core functions
we've been using thus far are in the clojure.core namespace:</p><pre><code class="klipse-clojure nohighlight">(clojure.core/println "hi")
</code></pre><p>That's the fully-qualified name of <code>println</code>. You'd normally have to
use the fully-qualified name for functions (or else use an alias to
the namespace --- covered in a moment), but Clojure makes all the
clojure.core functions automatically available by their unqualified
names (that is, sans namespace) for convenience.</p><p>Fully-qualified names are written "namespace/symbol". The namespace
may have dots in it, which correspond to directories in your
filesystem. For example, the function foo-bar.core/my-func corresponds
to the my-func function in src/foo_bar/core.clj. (It's just a bit of
the underlying Java platform showing through that you need to use
underscores in your directory names instead of dashes).</p><p>It's most common for one source code file to correspond to one
namespace, and often comprise one <em>library</em>. At the top of your source
file, you write <code>(ns whatever)</code> and that declares the namespace for
the rest of the file.</p><p>In the repl, you can make use of libraries --- and at the same time
provide a handy alias for them --- by <em>requiring</em> them like so:</p><pre><code class="klipse-clojure nohighlight">(require '[clojure.string :as str])
</code></pre><p>Now we can use all the functions in the clojure.string library by
prefixing them with "str/". We'll do exactly this in the section below
on <a href="index.html#functions-for-working-with-strings">Functions for working with
strings</a>.</p><h2 id="functions-for-creating-data-structures">Functions for Creating Data Structures</h2><p>There are functions for creating the various data structures without
using the usual literal syntax:</p><pre><code class="clojure">(list 1 2 3) ; ⇒ '(1 2 3)
(vector 1 2 3) ; ⇒ [1 2 3]
(hash-map :a 1 :b 2) ; ⇒ {:a 1 :b 2}
(hash-set :a :b :c) ; ⇒ #{:a :b :c}
</code></pre><p>And there are various functions for converting between vectors, sets,
and maps:</p><pre><code class="clojure">(def my-vec [1 2 3])
(set my-vec) ; ⇒ #{1 2 3}
(def my-map {:a 1 :b 2})
(vec my-map) ; ⇒ [[:a 1] [:b 2]]
(flatten (vec my-map)) ; ⇒ (:a 1 :b 2)
(set my-map) ; ⇒ #{[:b 2] [:a 1]}
(def my-set #{:a :b :c :d})
(vec my-set) ; ⇒ [:a :c :b :d]
;; And for fun:
(zipmap [:a :b :c] [1 2 3]) ; ⇒ {:c 3 :b 2 :a 1}
(apply hash-map [:a 1 :b 2]) ; ⇒ {:a 1 :b 2}
</code></pre><p>(We cover <code>apply</code> in the <a href="index.html#bread-and-butter-functions">Bread and Butter
functions</a> section.)</p><p>If you need to convert to a sequential collection but don't need fast
random access to items via index, you can use <code>seq</code> instead of <code>vec</code>
(to convert to a generic linked-list-like ("sequential") data
structure). More about <code>seq</code> when we get to <a href="index.html#laziness">Laziness</a>.</p><blockquote><p>By the way, you may have noticed a pattern here: longer function
names are for passing in values one-by-one to create the data
structure, whereas the shorter function names are for passing in a
whole data structure at once:</p><pre><code>literal long name short name
------- --------- ------------------
() list *{no short name}*
[] vector vec
{} hash-map *{no short name}*
#{} hash-set set
</code></pre><p>You might think of <code>seq</code> as the short name for <code>list</code>, but that's
probably pushing it, since there are a few differences.</p></blockquote><h2 id="functions-for-working-with-data-structures">Functions For Working With Data Structures</h2><p>Getting values from data structures:</p><pre><code class="clojure">;; Vectors
(def v [:a :b :c])
(nth v 1) ; ⇒ :b
(v 1) ; ⇒ :b (same)
(first v) ; ⇒ :a
(rest v) ; ⇒ (:b :c)
(next v) ; ⇒ (:b :c)
(last v) ; ⇒ :c
;; Lists
;; Same as vectors, but can't index.
;; Maps
(def m {:a 1 :b 2})
(get m :a) ; ⇒ 1
(m :a) ; ⇒ 1 (same)
(:a m) ; ⇒ 1 (same!)
(get m :x 44) ; ⇒ 44 (if no :x, 44 is the default)
(keys m) ; ⇒ (:a :b)
(vals m) ; ⇒ (1 2)
;; Grab a key or a val from a single map entry:
(key (first m)) ; ⇒ :a
(val (first m)) ; ⇒ 1
;; Of course, note that maps are not ordered.
;; Sets
(def s #{:a :b :c})
(s :a) ; ⇒ :a
(s :z) ; ⇒ nil
</code></pre><p>Data structures in Clojure are actually <em>immutable</em> --- you can't
change them. Though it may sound batty, it actually works out nicely
in practice, and we'll read more about in the
<a href="index.html#values,-immutability,-and-persistence">Immutability</a> section
below. For now, just note that data structures can't be mutated, but
we <em>can</em> get a new modified copy of a data structure:</p><pre><code class="clojure">;; Vectors
(def v [:a :b :c])
(def li '(:a :b :c))
(conj v :d) ; ⇒ [:a :b :c :d]
(conj li :d) ; ⇒ (:d :a :b :c)
v ; ⇒ is still [:a :b :c]
li ; ⇒ is still (:a :b :c)
;; Maps
(def m {:a 1 :b 2})
(assoc m :c 3) ; ⇒ {:a 1 :c 3 :b 2}
(dissoc m :b) ; ⇒ {:a 1}
m ; ⇒ is still {:a 1 :b 2}
;; Sets
(def s #{:a :b})
(conj s :c) ; ⇒ #{:a :c :b}
(disj s :a) ; ⇒ #{:b}
s ; ⇒ is still #{:a :b}
</code></pre><p>See the <a href="http://clojure.org/cheatsheet">cheatsheet</a> for much more
you can do with these core data structures.</p><h2 id="regular-expressions">Regular Expressions</h2><p>As you've seen, Clojure provides a handy literal syntax for regular
expressions: <code>#"regex here"</code>. Clojure uses the same regular expression
syntax as Java, which is nearly the same as what Perl 5 (and Python,
and Ruby) uses. You can read more about the specifics in the Java
<a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html">java.util.regex Pattern
docs</a>.</p><p>Clojure provides a number of functions for working with strings, and a
number of those can make use of regexes. See the next section for some
examples.</p><h2 id="functions-for-working-with-strings">Functions For Working With Strings</h2><p>There are a number of functions for working with strings listed in the
Strings section of the cheatsheet. Here are some examples of a few of
them:</p><pre><code class="clojure">(str "hi" "there")
;; ⇒ "hithere"
(count "hello")
;; ⇒ 5
(require '[clojure.string :as str])
;; ⇒ nil
(str/split "hello there" #" ")
;; ⇒ ["hello" "there"]
(str/join ["hello" "there"])
;; ⇒ "hellothere"
(str/join " " ["hello" "there"])
;; ⇒ "hello there"
(str/replace "hello there" "ll" "LL")
;; ⇒ "heLLo there"
</code></pre><p>Some of them make optional use of regexes. There's more in the
cheatsheet. Try them out!</p><p>Incidentally, since strings are sequential, any function that works on
sequentials works on strings. For example:</p><pre><code class="clojure">(first "hello")
;; ⇒ \h
(last "hello")
;; ⇒ \o
(rest "hello")
;; ⇒ (\e \l \l \o)
(nth "hello" 1)
;; ⇒ \e
(doseq [letter "hello"] (println letter))
;; h
;; e
;; l
;; l
;; o
;; ⇒ nil
</code></pre><p>Again, see the cheatsheet for more.</p><h2 id="values-immutability-and-persistence">Values, Immutability, and Persistence</h2><p>A <em>value</em> is fundamentally a constant thing; For example, the letter
"a" is a value. You don't "set" the letter "a" to some other value; it
always stays the letter "a". It's immutable. The value 10 is always
10. You can't ever "set 10 to 11". That makes no sense. If you want
11, you just use 11 instead of 10.</p><p>In Clojure, <em>all scalars and core data structures are like this</em>. They
are values. They are immutable. The map</p><pre><code class="clojure">{:name "John"
:hit-points 200
:super-power :resourcefulness}
</code></pre><p>is a value. If you want to "change" John's hit-points, you don't
change anything per se, but rather, you just conjure up a whole new
hashmap value.</p><p><strong>But wait:</strong> If you've done any imperative style programming in
C-like languages, this sounds crazy wasteful. <em>However</em>, the yin to
this immutability yang is that --- behind the scenes --- Clojure
shares data structures. It keeps track of all their pieces and
re-uses them pervasively. For example, if you have a 1,000,000-item
list and want to tack on one more item, you just tell Clojure, "give
me a new one but with this item added" --- and Clojure dutifully gives
you back a 1,000,001-item list in no time flat. Unbeknownst to you
it's re-using the original list.</p><p>Clojure data structures are said to be <em>persistent</em>.</p><p>And, again: this works just fine because to you the data structures
are all immutable. There is no "action at a distance". Other functions
can't change the value of a data structure you're working on because
values don't change.</p><blockquote><p>Note that, of course, Clojure doesn't do any unnecessary copying.
For example, when you pass a large data structure to a function</p><pre><code>(my-func a-really-big-data-structure)
</code></pre><p>it merely passes along a reference to the big data structure. You
can't change it in the caller's scope, because of course it's
immutable.</p><p>And of course, you don't get any action-at-a-distance in situations
like this either:</p><pre><code class="clojure">(def a [1 2 3 4 5])
(def b a)
;; Do what you will with `b`, ...
(my-func a) ; but it won't affect `a`.
</code></pre><p>since, regardless, you can't mutate the vector (neither via <code>b</code><em>nor</em> <code>a</code>).</p></blockquote><p>If you're wondering how the heck it's even possible to program at all
if you don't have "variables" and can't change anything, it will
become clear as we continue.</p><h2 id="control-structures">Control Structures</h2><p>Clojure has most of the usual control structures you'd expect to find,
for example: <code>if</code>, <code>and</code>, <code>or</code>, and <code>cond</code>. You can find them listed
in the <a href="http://clojure.org/cheatsheet">Cheatsheet</a>.</p><p>Note that they are all <em>expressions</em> in Clojure, and evaluate to
something. So, for example, this <code>if</code> expression:</p><pre><code class="clojure">(if motor-turning?
"yes"
"no")
</code></pre><p>Evaluates to either the value "yes" or the value "no".</p><p>Looping is handled by either using one of the various built-in
functions such as <code>map</code>, <code>filter</code>, <code>reduce</code>, <code>for</code>, etc., or else it's
handled by manually using <code>loop</code> and using recursion. We'll get to
these shortly.</p><p>Incidentally, looping is something that is required far less in
Clojure than in imperative languages like Python and Java. The
functions that Clojure provides often makes looping unnecessary.
For example, where in Python you might do something like this:</p><pre><code class="python">specific_stuff = []
for i in my_items:
if is_what_i_want(i):
specific_stuff.append(i)
</code></pre><p>in Clojure you lose the loop and it becomes:</p><pre><code class="clojure">(def specific-stuff (filter what-i-want? my-items))
</code></pre><p>This sort of thing comes up again and again, and we'll cover more
examples of it in the <a href="index.html#bread-and-butter-functions">Bread and Butter
functions</a> section.</p><h2 id="truthiness">Truthiness</h2><p>In <code>(if &lt;test&gt; &lt;then-this&gt; &lt;otherwise-this&gt;)</code> (and in <code>and</code>, <code>or</code>,
<code>cond</code>, etc. expressions), Clojure checks if the <code>&lt;test&gt;</code> evaluates to
something that looks either true or false. Clojure takes a very simple
approach here: <code>nil</code> and <code>false</code> are falsey; everything else is
truthy.</p><p>This means that zero, the empty string, and empty core data structures
are all true:</p><pre><code class="clojure">(if 0 :t :f) ; ⇒ :t
(if "" :t :f) ; ⇒ :t
(if [] :t :f) ; ⇒ :t
(if {} :t :f) ; ⇒ :t
(if #{} :t :f) ; ⇒ :t
</code></pre><p>If you want to check if one of those is <em>empty</em>, you could use the
<code>empty?</code> function, though, the docs recommend using this idiom:</p><pre><code class="clojure">(if (seq my-stuff)
"still has stuff left"
"all gone")
</code></pre><h2 id="equality">Equality</h2><p>You'll often check for equality using <code>=</code> (and likewise inequality
using <code>not=</code>), for example:</p><pre><code class="clojure">(if (= tries max-tries)
"you're done"
"keep going")
</code></pre><p><code>=</code> recursively checks equality of nested data structures (and
considers lists and vectors containing the same values in the same
order as equal), for example:</p><pre><code class="clojure">(= {:a [1 2 3] :b #{:x :y} :c {:foo 1 :bar 2}}
{:a '(1 2 3) :b #{:y :x} :c {:bar 2 :foo 1}})
;; ⇒ true
</code></pre><p>There's also a double-equals function <code>==</code> that is more forgiving
across various types of numbers:</p><pre><code class="clojure">(= 4 4.0)
;; ⇒ false
(== 4 4.0)
;; ⇒ true
</code></pre><p>See the docs for
<a href="http://clojuredocs.org/clojure_core/clojure.core/=">=</a> and
<a href="http://clojuredocs.org/clojure_core/clojure.core/==">==</a> for more
info.</p><h2 id="predicates-and-comparators">Predicates and Comparators</h2><p><em>Predicates</em> are functions that take one or more arguments and return
a true or false value. They usually are named with a trailing question
mark, for example, <code>even?</code>, <code>odd?</code>, <code>nil?</code>, etc. Though, some names
don't have the question mark, such as <code>&gt;</code>, <code>&gt;=</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>=</code>, <code>==</code>,
and <code>not=</code>.</p><p><em>Comparators</em> are functions that take 2 args and return -1, 0, or 1
depending upon whether the first arg is less than, equal to, or
greater than the second arg. The main one is <code>compare</code>.</p><h2 id="vars">Vars</h2><p>Near the top of this tutorial is the following definition:</p><pre><code class="clojure">(def the-answer 42)
</code></pre><p>The thing being defined here (behind the scenes) is officially called
a <em>Var</em>. The symbol "<code>the-answer</code>" refers to that var which itself
refers to the value 42:</p><p>the-answer (a symbol) → a var → 42 (a value).</p><p>When Clojure sees "<code>the-answer</code>", it automatically looks up the var,
then from there finds and returns the value 42.</p><p>Recall that <a href="index.html#let-and-locals">locals</a> don't involve vars at all:
those symbols refer directly to their values.</p><h2 id="functions-defining-your-own">Functions: Defining Your Own</h2><p>You can create a function using <code>fn</code>, and give it a name using <code>def</code>:</p><pre><code class="klipse-clojure nohighlight">(def my-func
(fn [a b]
(println "adding them!")
(+ a b)))
</code></pre><p>As you might guess, this actually creates the symbol <code>my-func</code> which
refers to a var which itself refers to the function (which is a
value). Call it:</p><pre><code class="klipse-clojure nohighlight">(my-func 10 20)
</code></pre><p>But for creating top-level functions, it's more convenient to use
<code>defn</code> (which uses <code>def</code> under the hood):</p><pre><code class="clojure">(defn my-func
"Docstring goes here."
[a b]
(println "adding them!")
(+ a b))
</code></pre><p>A few points to note:</p><ul><li>The function parameters (<code>a</code> and <code>b</code>) are present in a vector
(just like with the <code>let</code> expression, except we don't include
values for them).</li><li>Inside <code>my-func</code> you can do a sequence of operations if you like
(for example, our <code>println</code> call) --- just like in a <code>let</code> --- but
the value of the last expression is what the function call as a
whole will evaluate to.</li><li>Function definitions (using <code>defn</code>) should only go at the
"top-level".</li></ul><p>Functions can return data structures instead of just scalars:</p><pre><code class="clojure">(defn foo
[x]
[x (+ x 2) (* x 2)])
</code></pre><p>and you can of course pass them data structures as well:</p><pre><code class="clojure">(defn bar
[x]
(println x))
(bar {:a 1 :b 2})
(bar [1 2 3])
</code></pre><p>To define a function to take, say, two or more arguments:</p><pre><code class="clojure">(defn baz
[a b &amp; the-rest]
(println a)
(println b)
(println the-rest))
</code></pre><p>Any additional args you pass beyond the first two get packaged into a
sequence assigned to <code>the-rest</code>. To have that function take <em>zero</em> or
more arguments, change the parameter vector to just <code>[&amp; the-rest]</code>.</p><h3 id="layout-of-functions">Layout of Functions</h3><p>Your author likes to write his functions in a top-down fashion:</p><pre><code class="clojure">;; BROKEN pseudocode
(do-it)
(defn do-it
[]
(... (my-func-a ...)))
(defn my-func-a
[...]
(... (my-func-b ...)))
(defn my-func-b ...)
</code></pre><p>but Clojure doesn't like that because it wants to have at least
<em>heard</em> about a function before you write a call to it. To let Clojure
know about a function's existence, use <code>declare</code>:</p><pre><code class="clojure">;; pseudocode
(declare do-it)
(do-it)
(declare my-func-a)
(defn do-it
[]
(... (my-func-a ...)))
(declare my-func-b)
(defn my-func-a
[...]
(... (my-func-b ...)))
(defn my-func-b ...)
</code></pre><h2 id="side-effects">Side-effects</h2><p>Some expressions in Clojure have side-effects. Many do not. All
expressions evaluate to something.</p><p>For example, <code>(+ 1 2)</code> evaluates to 3 and has no side-effects.
<code>(println "hi")</code> evaluates to nil and has the side-effect of printing
"hi" to standard out. You usually call <code>println</code> for the side-effect,
not for the return value.</p><p>Pure functions are those which have no side-effects and which do not
depend upon anything outside to compute their return value(s): you
pass it one or more values, and it returns one or more values.</p><p>If you want to make an expression that has some side-effects before
it evaluates to a value, use <code>do</code>:</p><pre><code class="clojure">(do
(println "Spinning up warp drive, captain ...")
(spin-up-warp-drive)
(get-engine-temperature))
</code></pre><p>There are a handful of functions/macros/special-forms in Clojure for
making use of side-effects, and they are spelled with a "do" at the
beginning. Try these on for size:</p><pre><code class="klipse-clojure nohighlight">(def my-items ["shirt" "coat" "hat"])
(doseq [i my-items]
(println i))
</code></pre><pre><code class="klipse-clojure nohighlight">(dotimes [i 10]
(println "counting:" i))
</code></pre><p>There's also <code>dorun</code> and <code>doall</code>, both of which are discussed below in
the section on <a href="index.html#laziness">Laziness</a>.</p><p>We say that <code>let</code> expressions and function bodies (and also <code>loop</code>
expressions, which you'll read about later in <a href="index.html#looping-and-recursion">Looping and
Recursion</a>) have an "implicit do": within them
you can list expressions one after another, and they all get evaluated
in order (presumably for the side-effects), but the last one is what
determines the overall resulting value of the <code>let</code> expression.</p><blockquote><p>Incidentally, if in the binding vector of a <code>let</code> you'd like to have
some side-effects happen and aren't really concerned about the local
values involved, it's customary to use "_" (an underscore) as the
identifier:</p><pre><code class="clojure">(let [_ (do-something)
_ (println "done with that")
x 10]
...)
</code></pre><p>There's nothing special about the identifier "_" --- it's just
shorter to type than, say, "this-is-of-no-consequence".</p></blockquote><p>There's a version of <code>if</code> which supports no "else" expression and
which provides an "implicit do": it's spelled "<code>when</code>" (and likewise
with <code>if-not</code><code>when-not</code>).</p><h2 id="destructuring">Destructuring</h2><p>Clojure provides a little bit of extra syntactic support for assigning
values to locals in <code>let</code> expressions and function definitions. Using
<code>let</code> as an example, suppose you have a nested data structure, and
you'd like to assign some values in it to locals. Where you <em>could</em> do
this:</p><pre><code class="clojure">(def games [:chess :checkers :backgammon :cards])
(let [game-a (games 0)
game-b (games 1)
game-c (games 2)
game-d (games 3)]
...
...)
</code></pre><p>Destructuring allows you to instead write:</p><pre><code class="clojure">(let [[game-a game-b game-c game-d] games]
...
...)
</code></pre><p>The thing to the left of "games" in the binding vector is referred to
as the "binding form". In the above case, the binding form is a
vector.</p><p>The way it works is: if the binding form is a vector, Clojure assumes
that the thing you're trying to assign to it must also be a vector,
and so it unpacks the values from that data structure into the
corresponding items listed in the binding form.</p><p>If you want to omit one or more of the values in the <code>games</code>, you
can do so like this:</p><pre><code class="clojure">(let [[_ my-game _ your-game] games]
...
...)
</code></pre><p>The underscore is just used as a placeholder. It's a valid identifier,
but conventionally used when you don't care what value it gets. Above,
my-game gets :checkers and your-game gets :cards.</p><p>Destructuring also works for maps in additon to vectors. For example,
instead of:</p><pre><code class="clojure">(def concert {:band "The Blues Brothers"
:location "Palace Hotel Ballroom"
:promos "Ladies night, tonight"
:perks "Free parking"})
(let [band (concert :band)
location (concert :location)
promos (concert :promos)
perks (concert :perks)]
...
...)
</code></pre><p>you <em>could</em> do:</p><pre><code class="clojure">(let [{band :band
location :location
promos :promos
perks :perks} concert]
...
...)
</code></pre><p>but an even better shortcut that destructuring provides for that is:</p><pre><code class="clojure">(let [{:keys [band location promos perks]} concert]
...
...)
</code></pre><h2 id="laziness">Laziness</h2><p>Most of the sequences Clojure creates (via calls to <code>map</code>, <code>reduce</code>,
<code>filter</code>, <code>for</code>, etc. --- covered in the next section) are <em>lazy</em>. A
lazy sequence is one that isn't <em>realized</em> (computed) all at
once. Instead, its values are only realized when you ask for them. If
you've only asked for the first 5 values of a lazy seq, then that seq
consists of 5 values plus a box that makes more values only when you
ask for them. .</p><p>A nice feature of laziness is that you can create lazy infinite
sequences but only realize (and consume memory for) the first <em>n</em> that
you actually need.</p><p>Be aware that the repl causes lazy lists to be fully realized if you
ask to see their value (which one is apt to do). After using the repl
for a while, you start to get a false sense of eagerness. <code>;)</code></p><p>If you've got some code that generates a lazy seq and you want to realize
the whole thing right then and there, you can either use</p><ul><li><code>(doall my-lazy-seq)</code> (to get the whole thing), or else</li><li><code>(dorun my-lazy-seq)</code> (to realize each value (presumably for some
side-effects you're expecting to get in the process) but then
forget it as you proceed to realize the next one).</li></ul><h2 id="bread-and-butter-functions">Bread and Butter Functions</h2><p>Given Clojure's extensive use of immutability, persistent data
structures, and laziness, one of its strong suits is functional
programming. To this author, functional programming means:</p><ul><li>treating functions just like any other regular value (for example,
passing them as args to other functions)</li><li>writing and using functions that return other functions</li><li>avoiding mutable state, preferring instead Clojure's functional
alternatives (<code>map</code>, <code>filter</code>, <code>reduce</code>, etc.) or else just
directly using recursion.</li></ul><p>Let's try out some of the power tools that Clojure comes with. In the
subsections that follow, we've left out the corresponding links to
clojuredocs for the given functions, but you'll probably want to read
the docs and see the examples there to get the full story for each.</p><h3 id="map">map</h3><p>With <code>map</code> you can apply a function to every value in a collection.
The result is a new collection. You can often use <code>map</code> instead of
manually looping over a collection. Some examples using <code>map</code>:</p><pre><code class="klipse-clojure nohighlight">(map inc [10 20 30])
</code></pre><pre><code class="klipse-clojure nohighlight">(map str [10 20 30])
</code></pre><pre><code class="klipse-clojure nohighlight">;; You can define the function to be used on-the-fly:
(map (fn [x] (str "=" x "=")) [10 20 30])
</code></pre><pre><code class="klipse-clojure nohighlight">;; And `map` knows how to apply the function you give it
;; to multiple collections in a coordinated way:
(map (fn [x y] (str x y)) [:a :b :c] [1 2 3])
</code></pre><p>When working on more than one collection at a time, <code>map</code> is smart
enough to stop when the shorter of the colls runs out of items:</p><pre><code class="klipse-clojure nohighlight">(map (fn [x y] (str x y)) [:a :b :c] [1 2 3 4 5 6 7])
</code></pre><h3 id="filter-and-remove">filter and remove</h3><p>Use <code>filter</code> with a predicate function to pare down a collection to
just the values for which <code>(the-pred the-value)</code> returns true:</p><pre><code class="klipse-clojure nohighlight">(filter odd? (range 10))
</code></pre><p>Use <code>remove</code> for the opposite effect (which amounts to <em>removing</em> the
items for which <code>(pred val)</code> returns true):</p><pre><code class="klipse-clojure nohighlight">(remove odd? (range 10))
</code></pre><p>You will often find yourself using these functions instead
of writing loops like in imperative languages.</p><h3 id="apply">apply</h3><p><code>apply</code> is for when you have a function which takes individual args,
for example, <code>max</code>, but the values you'd like to pass to it are in a
collection. <code>apply</code> "unpacks" the items in the coll:</p><pre><code class="klipse-clojure nohighlight">(max 1 5 2 8 3)
</code></pre><pre><code class="clojure">(max [1 5 2 8 3]) ;; ERROR
</code></pre><pre><code class="klipse-clojure nohighlight">(apply max [1 5 2 8 3])
</code></pre><p>A nice feature of <code>apply</code> is that you can supply extra args which
you'd like to be treated as if they were part of the collection:</p><pre><code class="klipse-clojure nohighlight">(apply max 4 55 [1 5 2 8 3])
</code></pre><h3 id="for">for</h3><p><code>for</code> is for generating collections from scratch (again, without
needing to resort to manually looping). <code>for</code> is similar to Python's
"list comprehensions". Some examples of using <code>for</code>:</p><pre><code class="klipse-clojure nohighlight">(for [i (range 10)] i)
</code></pre><pre><code class="klipse-clojure nohighlight">(for [i (range 10)] (* i i))
</code></pre><pre><code class="klipse-clojure nohighlight">(for [i (range 10) :when (odd? i)] [i (str "&lt;" i "&gt;")])
</code></pre><p>Notice we snuck a "<code>:when (odd? i)</code>" in there. <code>for</code> even supports a
<code>:let</code> modifier in there to set up your values before getting to the
body of the <code>for</code> expression.</p><h3 id="reduce">reduce</h3><p><code>reduce</code> is a gem. You use it to apply a function to the first and
second items in a coll and get a result. Then you apply it to the
result you just got and the 3rd item in the coll. Then the result of
<em>that</em> and the 4th. And so on. The process looks something like this:</p><pre><code class="clojure">(reduce + [1 2 3 4 5])
;; → 1 + 2 [3 4 5]
;; → 3 [3 4 5]
;; → 3 + 3 [4 5]
;; → 6 [4 5]
;; → 6 + 4 [5]
;; → 10 [5]
;; → 10 + 5
;; =&gt; 5
</code></pre><p>And, of course, you can supply your own function if you like:</p><pre><code class="clojure">(reduce (fn [x y] ...) [...])
</code></pre><p>A nice additional feature of <code>reduce</code> is that you can supply a value
for it to start off with:</p><pre><code class="klipse-clojure nohighlight">(reduce + 10 [1 2 3 4 5])
</code></pre><p>This by itself is pretty handy. But it gets even better. Since you can
supply an initial argument, and you can supply your own function, you
can use a <em>data structure</em> as that initial argument and have your
function "build it up" as you go. For example:</p><pre><code class="clojure">(reduce (fn [accum x]
(assoc accum
(keyword x)
(str x \- (rand-int 100))))
{}
["hi" "hello" "bye"])
;; → {}
;; → {:hi "hi-29"}
;; → {:hi "hi-29" :hello "hello-42"}
;; ⇒ {:hi "hi-29" :hello "hello-42" :bye "bye-10"}
</code></pre><p>Building up some accumulator using <code>reduce</code> and your own custom
function is a fairly common pattern (and once again allows us to
avoid looping and manipulations of anything mutable).</p><h3 id="partial-comp-and-iterate">partial, comp, and iterate</h3><p>With <code>partial</code> you can create a function which wraps another one and
passes it some standard arguments every time, along with the ones you
supply right when you call it. For example:</p><pre><code class="klipse-clojure nohighlight">(defn lots-of-args [a b c d] (str/join "-" [a b c d]))
</code></pre><pre><code class="klipse-clojure nohighlight">(lots-of-args 10 20 30 40)
</code></pre><pre><code class="klipse-clojure nohighlight">(def fewer-args (partial lots-of-args 10 20 30))
</code></pre><pre><code class="klipse-clojure nohighlight">(fewer-args 40)
</code></pre><pre><code class="klipse-clojure nohighlight">(fewer-args 99)
</code></pre><p><code>comp</code> is for composing a function from other ones. That is, <code>(comp foo bar baz)</code> gives you a function that will first call baz on
whatever you pass it, then bar on the result of that, then foo on the
result of <em>that</em>, and finally returns the result. Here's a silly
example:</p><pre><code class="klipse-clojure nohighlight">(defn wrap-in-stars [s] (str "*" s "*"))
</code></pre><pre><code class="klipse-clojure nohighlight">(defn wrap-in-equals [s] (str "=" s "="))
</code></pre><pre><code class="klipse-clojure nohighlight">(defn wrap-in-ats [s] (str "@" s "@"))
</code></pre><pre><code class="klipse-clojure nohighlight">(def wrap-it (comp wrap-in-ats
wrap-in-equals
wrap-in-stars))
</code></pre><pre><code class="klipse-clojure nohighlight">(wrap-it "hi")
</code></pre><pre><code class="klipse-clojure nohighlight">;; Which is the same as:
(wrap-in-ats (wrap-in-equals (wrap-in-stars "hi")))
</code></pre><p><code>(iterate foo x)</code> yields an infinite lazy list consisting
of:</p><pre><code class="clojure">(x
(foo x)
(foo (foo x))
(foo (foo (foo x)))
...)
</code></pre><p>To just take the first, say, 5 values from an infinite list, try this:</p><pre><code class="klipse-clojure nohighlight">(defn square [x] (* x x))
</code></pre><pre><code class="klipse-clojure nohighlight">(take 5 (iterate square 2))
</code></pre><h2 id="looping-and-recursion">Looping and Recursion</h2><p>As you've seen in the previous section, looping is often just handled
by various built-in functions such as <code>map</code>, <code>filter</code>, and <code>reduce</code>.
You should use those whenever you can. For times when you need more
manual control, you can write loops yourself. By-hand.</p><p>A <code>loop</code> expression looks like a <code>let</code>; you set up locals in its
binding vector, then the body of the loop is executed. The body has an
implicit do, just like <code>let</code> and function bodies. However, within the
body of the <code>loop</code> expression you exit at some point with what you
have or else loop again. When you loop again, you call the loop (using
<code>recur</code>) as if it's a function, passing new values in for the ones you
previously set up in the binding vector. The loop calling itself like
this is called <em>recursion</em>. Here's a trivial example:</p><pre><code class="klipse-clojure nohighlight">(loop [accum []
i 1]
(if (= i 10)
accum
(recur (conj accum i)
(inc i))))
</code></pre><p>The state in this loop is carried in the <code>accum</code> vector, which we
update each time through the loop. <code>i</code> is the counter, and we finally
exit the loop (which evaluates to <code>accum</code>) when i equals 10.</p><p><code>accum</code> could be any other data structure, and that call <code>(conj accum i)</code> could be any expression that yields a new data structure to take
the old one's place the next time through.</p><p>You don't actually need a <code>loop</code> to use <code>recur</code>. If you use <code>recur</code> in
a function body, it will just call the function again, replacing the
args it was previously called with with the ones you pass to <code>recur</code>.</p><p>Finally, recall that if you just need looping for the side-effects
only, see <code>doseq</code> and <code>dotimes</code>.</p><h2 id="reference-types">Reference Types</h2><p>Although we've been saying all along that Clojure doesn't have
"variables", and that everything is immutable, ... that's not entirely
true.</p><p>For when you really do need mutability, Clojure offers <em>reference
types</em>. And Clojure provides built-in support for helping you mutate
them in safe ways.</p><p>Aside from vars (which is a sort of special reference type), there are
3 kinds of reference types:</p><ul><li>Atoms</li><li>Refs</li><li>Agents</li></ul><p>You might typically create a reference type like this:</p><pre><code class="clojure">(def my-atom (atom {}))
</code></pre><p>This reference type is an atom, and its state is a hashmap (an empty
one, for now). Here, the <code>my-atom</code> symbol refers to a var which refers
to the atom.</p><p>Although you <em>still</em> can't literally change the value of the atom, you
<em>can</em> swap in a new hashmap value for it any time you like. To retrieve
the value of the atom, you "deref" it, or just use the shorter "@"
syntax. Here's an (atom-specific) example:</p><pre><code class="klipse-clojure nohighlight">(def my-atom (atom {:foo 1}))
</code></pre><pre><code class="klipse-clojure nohighlight">@my-atom
</code></pre><pre><code class="klipse-clojure nohighlight">(swap! my-atom update-in [:foo] inc)
</code></pre><pre><code class="klipse-clojure nohighlight">@my-atom
</code></pre><p>... and we've just changed the state of the atom. (Note, <code>swap!</code> is a
function used only for atoms. There are other specific functions for
working with the other reference types.)</p><p>The point of having reference types is that, in your programs, you may
want to represent an <em>identity</em>. An identity is something that may
change its state over time, but is still the same entity,
regardless. In Clojure, an identity is represented by a reference
type, and its state is represented by a value.</p><p>We won't discuss reference types further in this tutorial. Perhaps
someone will write a good topical guide...</p><h2 id="see-also">See Also</h2><ul><li><a href="https://www.4clojure.com/">4Clojure</a> --- try out what you've
learned so far by interactively solving a set of interesting
programming problems.</li></ul><h2 id="not-covered-in-this-tutorial">Not Covered In This Tutorial</h2><p>To keep this tutorial down to a manageable length, advanced topics or
other far (or not so far) corners not covered herein include but
aren't limited to: function literals, multiple-arity functions,
exceptions, dynamic scoping of vars, namespaced keywords, metadata,
any substantial coverage of macros, transients, zippers, delays,
futures, promises, refs, agents or anything about multithreading,
thread-first, thread-last, trampolines, datatypes, protocols,
multimethods, and Java interop.</p><h2 id="contributors">Contributors</h2><p>John Gabriele <a href="mailto:jmg3000@gmail.com">jmg3000@gmail.com</a> (original author)</p>
<div id="prev-next">
<a href="../getting_started/index.html">&laquo; Getting Started with Clojure</a>
||
<a href="../emacs/index.html">Clojure with Emacs &raquo;</a>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div id="sidebar">
<h3>Links</h3>
<ul id="links">
<li><a href="../../about/index.html">About</a></li>
<li><a href="../../content/index.html">Table of Contents</a></li>
<li><a href="../getting_started/index.html">Getting Started with Clojure</a></li>
<li><a href="index.html">Introduction to Clojure</a></li>
<li><a href="../emacs/index.html">Clojure with Emacs</a></li>
<li><a href="../vim_fireplace/index.html">Clojure with Vim and fireplace.vim</a></li>
<li><a href="../eclipse/index.html">Starting with Eclipse and Counterclockwise For Clojure Development</a></li>
<li><a href="../basic_web_development/index.html">Basic Web Development</a></li>
<li><a href="../parsing_xml_with_zippers/index.html">Parsing XML in Clojure</a></li>
<li><a href="../growing_a_dsl_with_clojure/index.html">Growing a DSL with Clojure</a></li>
<li><a href="../../language/core_overview/index.html">Overview of clojure.core, the standard Clojure library</a></li>
<li><a href="../../language/namespaces/index.html">Clojure Namespaces and Vars</a></li>
<li><a href="../../language/collections_and_sequences/index.html">Collections and Sequences in Clojure</a></li>
<li><a href="../../language/functions/index.html">Functions in Clojure</a></li>
<li><a href="../../language/laziness/index.html">Laziness in Clojure</a></li>
<li><a href="../../language/interop/index.html">Clojure interoperability with Java</a></li>
<li><a href="../../language/macros/index.html">Clojure Macros and Metaprogramming</a></li>
<li><a href="../../language/polymorphism/index.html">Polymorphism in Clojure: Protocols and Multimethods</a></li>
<li><a href="../../language/concurrency_and_parallelism/index.html">Concurrency and Parallelism in Clojure</a></li>
<li><a href="../../language/glossary/index.html">Clojure Terminology Guide</a></li>
<li><a href="../../ecosystem/libraries_directory/index.html">A Directory of Clojure Libraries</a></li>
<li><a href="../../ecosystem/libraries_authoring/index.html">Library Development and Distribution</a></li>
<li><a href="../../ecosystem/generating_documentation/index.html">Generating Documentation</a></li>
<li><a href="../../ecosystem/data_processing/index.html">Data Processing (Help Wanted)</a></li>
<li><a href="../../ecosystem/web_development/index.html">Web Development (Overview)</a></li>
<li><a href="../../ecosystem/maven/index.html">How to use Maven to build Clojure projects</a></li>
<li><a href="../../ecosystem/community/index.html">Clojure Community</a></li>
<li><a href="../../ecosystem/user_groups/index.html">Clojure User Groups</a></li>
<li><a href="../../ecosystem/running_cljug/index.html">Running a Clojure User Group</a></li>
<li><a href="../../ecosystem/books/index.html">Books about Clojure and ClojureScript</a></li>
<li><a href="../../cookbooks/data_structures/index.html">Data Structures (Help wanted)</a></li>
<li><a href="../../cookbooks/strings/index.html">Strings</a></li>
<li><a href="../../cookbooks/math/index.html">Mathematics with Clojure</a></li>
<li><a href="../../cookbooks/date_and_time/index.html">Date and Time (Help wanted)</a></li>
<li><a href="../../cookbooks/files_and_directories/index.html">Working with Files and Directories in Clojure</a></li>
<li><a href="../../cookbooks/middleware/index.html">Middleware in Clojure</a></li>
<li><a href="../../ecosystem/java_jdbc/home.html">java.jdbc - Getting Started</a></li>
<li><a href="../../ecosystem/java_jdbc/using_sql.html">java.jdbc - Manipulating data with SQL</a></li>
<li><a href="../../ecosystem/java_jdbc/using_ddl.html">java.jdbc - Using DDL and Metadata</a></li>
<li><a href="../../ecosystem/java_jdbc/reusing_connections.html">java.jdbc - How to reuse database connections</a></li>
<li><a href="../../ecosystem/core_typed/home/index.html">core.typed - User Documentation Home</a></li>
<li><a href="../../ecosystem/core_typed/user_documentation/index.html">core.typed - User Documentation</a></li>
<li><a href="../../ecosystem/core_typed/rationale/index.html">core.typed - Rationale</a></li>
<li><a href="../../ecosystem/core_typed/quick_guide.html">core.typed - Quick Guide</a></li>
<li><a href="../../ecosystem/core_typed/start/introduction_and_motivation/index.html">core.typed - Getting Started: Introduction and Motivation</a></li>
<li><a href="../../ecosystem/core_typed/types/index.html">core.typed - Types</a></li>
<li><a href="../../ecosystem/core_typed/start/annotations/index.html">core.typed - Annotations</a></li>
<li><a href="../../ecosystem/core_typed/poly_fn/index.html">core.typed - Polymorphic Functions</a></li>
<li><a href="../../ecosystem/core_typed/filters/index.html">core.typed - Filters</a></li>
<li><a href="../../ecosystem/core_typed/mm_protocol_datatypes/index.html">core.typed - Protocols</a></li>
<li><a href="../../ecosystem/core_typed/loops/index.html">core.typed - Looping constructs</a></li>
<li><a href="../../ecosystem/core_typed/function_types/index.html">core.typed - Functions</a></li>
<li><a href="../../ecosystem/core_typed/limitations/index.html">core.typed - Limitations</a></li>
</ul>
</div>
</div>
</div>
<footer>Copyright &copy; 2021 Multiple Authors
<p style="text-align: center;">Powered by <a href="http://cryogenweb.org">Cryogen</a></p></footer>
</div>
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="../../../js/highlight.pack.js" type="application/javascript"></script>
<script>hljs.initHighlightingOnLoad();</script>
<link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css">
<script>
window.klipse_settings = {
"selector" : ".klipse-clojure"
};
</script>
<script src="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
</body>
</html>