-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1828 lines (1572 loc) · 101 KB
/
index.html
File metadata and controls
1828 lines (1572 loc) · 101 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Clojure Notes</title>
<meta name="keywords" content="clojure notes,clojure programming,notes on clojure,clojure learning,clojure, clojure for dummies" />
<meta name="description" content="Clojure notes for beginners to start programming in Clojure." />
<meta name="robots" content="index,follow" />
<meta http-equiv="Expires" content="0" />
<meta name="revisit-after" content="1 days" />
<link rel="stylesheet" type="text/css" href="static/mystyle.css" />
<link rel="icon" type="image/ico" href="http://rubylearning.com/images/favicon.ico" />
<!-- Syntax highlighting -->
<!-- Include required JS files -->
<script type="text/javascript" src="static/shCore.js"></script>
<!-- At least one brush, here we choose JS. You need to include a brush for every language you want to highlight -->
<script type="text/javascript" src="static/shBrushClojure.js"></script>
<!-- Include *at least* the core style and default theme -->
<link href="static/shCore.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="Stylesheet" href="static/shThemeDefault.css" />
<base href="http://clojure-notes.rubylearning.org/" />
<!-- Google Analytics code -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-59044-14']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<!-- Google Analytics code ends -->
</head>
<body>
<div>
<h1>Clojure Notes <img src="http://rubylearning.com/images/clojure-icon.gif" alt="Clojure" /></h1>
<h2>Buy the eBook</h2>
<p>The <strong><a href="http://clojure-notes.rubylearning.org/clojureforbeginners.html">Clojure for Beginners</a></strong> eBook contains all the topics covered here. The eBook is over 70 pages and is in pdf format. The cost of this eBook is only <b>US$ 7</b> and is being collected to help me maintain the site and the eBook, and also provide quality content to you. Click on the image below to buy the eBook.</p>
<p class="float-left;"><a href="http://clojure-notes.rubylearning.org/clojureforbeginners.html"><img src="images/cfb.jpg" alt="Clojure for Beginners eBook" title="Clojure for Beginners eBook" /></a></p>
<h2>Table of Contents</h2>
<ul>
<li><span style="color: #663366; font-size:115%">0.0 NOTES FOR WHOM?</span></li>
<li><a href="/#preamble">0.1 Preamble</a></li>
<li><a href="/#feedback">0.2 Feedback</a></li>
<li><span style="color: #663366; font-size:115%">1.0 INTRODUCTION TO CLOJURE</span></li>
<li><a href="/#wc">1.1 What is Clojure?</a></li>
<li><span style="color: #663366; font-size:115%">2.0 GETTING STARTED</span></li>
<li><a href="/#labrepl">2.1 Option: Labrepl Download and Installation (for MS Windows)</a>
<ul>
<li>2.1.1 What's Labrepl?</li>
<li>2.1.2 Downloading and Installing Labrepl (for MS Windows)</li>
<li>2.1.3 Starting the REPL</li>
<li>2.1.4 Loading a file in the REPL</li>
</ul>
</li>
<li><a href="/#cbdw">2.2 Option: Clojure Box Download and Installation (for MS Windows)</a>
<ul>
<li>2.2.1 Test if Clojure Box works</li>
<li>2.2.2 Loading a file in Clojure Box</li>
</ul>
</li>
<li><a href="/#nbdw">2.3 Option: NetBeans/Enclojure Download and Installation (for MS Windows)</a>
<ul>
<li>2.3.1 To create a Clojure Project in NetBeans</li>
<li>2.3.2 To start the REPL in NetBeans</li>
<li>2.3.3 Anatomy of the Enclojure REPL Panel</li>
</ul>
</li>
<li><a href="/#syntax">2.4 Syntax</a></li>
<li><a href="/#com">2.5 Comments</a></li>
<li><a href="/#ccg">2.6 Clojure Coding Guidelines & Naming Convention</a></li>
<li><a href="/#forms">2.7 Forms</a></li>
<li><a href="/#symbols">2.8 Symbols</a></li>
<li><a href="/#vandb">2.9 Vars and Bindings</a></li>
<li><a href="/#literals">2.10 Literals</a>
<ul>
<li>2.10.1 Booleans and nil</li>
<li>2.10.2 Numbers
<ul>
<li>2.10.2.1 Arbitrary-precision arithmetic</li>
<li>2.10.2.2 format</li>
</ul>
</li>
<li>2.10.3 Characters and Strings</li>
<li>2.10.4 Keywords</li>
</ul>
</li>
<li><a href="/#ex110">2.11 Exercises</a>
<ul>
<li>2.11.1 Exercise 1</li>
<li>2.11.2 Exercise 2</li>
</ul>
</li>
<li><span style="color: #663366; font-size:115%">3.0 CHARGING AHEAD</span></li>
<li><a href="/#collect">3.1 A Quick look at Collections</a>
<ul>
<li>3.1.1 Lists</li>
<li>3.1.2 Vectors</li>
<li>3.1.3 Sets</li>
<li>3.1.4 Maps</li>
<li>3.1.5 Some functions on collections
<ul>
<li>3.1.5.1 count function</li>
<li>3.1.5.2 reverse function</li>
<li>3.1.5.3 apply function</li>
<li>3.1.5.4 map function</li>
</ul>
</li>
</ul>
</li>
<li><a href="/#seq">3.2 Sequences</a>
<ul>
<li>3.2.1 seq</li>
<li>3.2.2 first</li>
<li>3.2.3 rest</li>
<li>3.2.4 cons</li>
<li>3.2.5 next</li>
<li>3.2.6 conj, into</li>
<li>3.2.7 range</li>
<li>3.2.8 repeat</li>
<li>3.2.9 iterate, take</li>
<li>3.2.10 concat</li>
</ul>
</li>
<li><a href="/#fc">3.3 Flow Control</a>
<ul>
<li>3.3.1 if, if-not</li>
<li>3.3.2 cond, condp</li>
<li>3.3.3 when, when-not</li>
<li>3.3.4 do</li>
</ul>
</li>
<li><a href="/#defunc">3.4 Defining Functions</a>
<ul>
<li>3.4.1 Exercise</li>
<li>3.4.2 Exercise</li>
<li>3.4.3 Exercise</li>
</ul>
</li>
<li><a href="/#doc">3.5 Documentation</a>
<ul>
<li>3.5.1 Using doc</li>
<li>3.5.2 find-doc</li>
<li>3.5.3 Documenting a function</li>
<li>3.5.4 Clojure API</li>
</ul>
</li>
<li><span style="color: #663366; font-size:115%">4.0 CLOJURE AND JAVA</span></li>
<li><a href="/#java">4.1 Working with Java</a>
<ul>
<li>4.1.1 Importing multiple classes</li>
<li>4.1.2 Create a Java object</li>
<li>4.1.3 Accessing methods</li>
<li>4.1.4 ..chains</li>
<li>4.1.5 doto</li>
<li>4.1.6 Accessing static fields</li>
<li>4.1.7 Accessing static methods</li>
<li>4.1.8 -> macro</li>
<li>4.1.9 Exception handling</li>
<li>4.1.10 Some More Examples</li>
<li>4.1.11 Source for a function</li>
<li>4.1.12 Inspector</li>
</ul>
</li>
<li><span style="color: #663366; font-size:115%">5.0 DIVING INTO CLOJURE</span></li>
<li><a href="/#ns">5.1 Namespaces</a>
<ul>
<li>5.1.1 in-ns function</li>
<li>5.1.2 ns</li>
</ul>
</li>
<li><a href="/#bind">5.2 More on Bindings</a>
<ul>
<li>5.2.1 let</li>
<li>5.2.2 binding</li>
</ul>
</li>
<li><a href="/#es">5.3 Echo Server</a>
<ul>
<li>5.3.1 Port</li>
<li>5.3.2 Socket</li>
<li>5.3.3 clojure-contrib library</li>
<li>5.3.4 server-socket API</li>
<li>5.3.5 duck-streams API
<ul>
<li>5.3.5.1 spit function</li>
</ul>
</li>
<li>5.3.6 Step 1: Define a namespace</li>
<li>5.3.7 Step 2: Define a port</li>
<li>5.3.8 Step 3: Define a function</li>
<li>5.3.9 Step 4: Start the server</li>
<li>5.3.10 Step 5: Test the Echo Server</li>
</ul>
</li>
<li><a href="/#sm">5.4 StructMaps</a></li>
<li><a href="/#refs">5.5 Refs</a></li>
<li><a href="/#trans">5.6 Transactions</a>
<ul>
<li>5.6.1 A Simple Accounts example</li>
</ul>
</li>
<li><a href="/#compile">5.7 Compiling using Clojure Box</a></li>
<li><a href="/#ref">References</a></li>
</ul>
<h2>0.0 NOTES FOR WHOM?</h2>
<h2><a name="preamble">0.1 Preamble</a></h2>
<ul>
<li><b>These study notes are for absolute beginners in Clojure</b>.</li>
<li>Some previous programming background is essential.</li>
<li>Some parts require knowledge of <img src="http://rubylearning.com/images/coffee_cup.gif" alt="Java" /> Java.</li>
<li>The programs in these study notes have been tested using the Clojure 1.2 version.</li>
<li>Since I have a Windows box, I have mentioned the installation of Clojure and other dependencies for MS Windows only.</li>
<li>I recommend that you go through the notes topic by topic (sequentially), reading the text, running the provided examples and doing the assignments along the way. This will give you a much broader understanding of how things are done (and of how you can get things done), and it will reduce the chance of anxiety, confusion, and worse yet, mistakes.</li>
</ul>
<h2><a name="feedback">0.2 Feedback</a></h2>
<p>The site is currently in alpha and I need your help to make it a great community resource, so please let me know if you've got any feedback on how to make this site better. Send in your feedback and suggestions to <b>satishtalim [at] gmail [dot] com</b>.</p>
<p><b>I can send you a .pdf file of these Clojure Notes. Please email me if interested.</b></p>
<h2>1.0 INTRODUCTION TO CLOJURE</h2>
<h2><a name="wc">1.1 What is Clojure?</a></h2>
<p><strong>Clojure</strong> is a dynamically-typed, <a href="http://en.wikipedia.org/wiki/Functional_programming">functional programming</a> language that runs on the JVM (Java 5 or greater) and provides interoperability with Java.</p>
<p>"A key characteristic of Clojure is that it is a <em>functional language</em>, which means that functions are the fundamental building-block for programs rather than instructions, as is the case in most other programming languages (known as imperative languages). In Clojure, functions are best thought of as more like their counterparts in mathematics – a function is simply an operation that takes a number of parameters (also called arguments), and returns a value. These functions always return the same result when passed the same arguments. Imperative languages perform complex tasks by executing large numbers of instructions, which sequentially modify a program state until a desired result is achieved. Functional languages achieve the same goal through nested function composition – passing the result of one function as a parameter to the next. By composing and chaining function calls, along with recursion (a function calling itself), a functional program can express any possible task that a computer is capable of performing. An entire program can itself be viewed as a single function, defined in terms of smaller functions. The nesting structure determines the computational flow, and all the data is handled through function parameters and return
values." - From <a href="http://apress.com/book/view/1430272317">Practical Clojure</a>.</p>
<p>A major goal of Clojure is managing <em>concurrency</em>. Wikipedia has a great definition of concurrency: "Concurrency is a property of systems in which several computations are executing and overlapping in time, and potentially interacting with each other. The overlapping computations may be executing on multiple cores in the same chip, preemptively time-shared threads on the same processor, or executed on physically separated processors." The primary challenge of concurrency is managing access to a shared, mutable state.</p>
<p>Clojure helps you write correct concurrent programs by emphasizing immutability. Clojure enforces isolating changes in mutable state as either atomic operation with atoms, within a transaction with <b>refs</b>, or asynchronously with agents. Additionally, there are no explicit locks in Clojure, so this common source of deadlock is removed.</p>
<p>Michael Fogus, author of the book "<a href="http://www.manning.com/fogus/">The Joy of Clojure</a>" says that - "Clojure was born out of creator Rich Hickey's desire to avoid many of the complications, both inherent and incidental, of developing <em>concurrent applications</em> using Java and C++. The Java Virtual Machine is an amazingly practical platform -- it is mature, fast, and widely deployed. It supports a variety of hardware and operating systems and has a staggering number of libraries and support tools available, all of which Clojure can take advantage of, thus allowing prospective developers to avoid the costs of maintaining yet another infrastructure while leveraging existing libraries."</p>
<p>The following shows briefly, the release dates for various versions of Clojure:</p>
<ul>
<li>1.2 is expected soon though beta version is available.</li>
<li>1.1 (the current version) released in Dec. 2009.</li>
<li>1.0 released in May 2009.</li>
<li>Clojure was first released on October 16, 2007.</li>
</ul>
<h2>2.0 GETTING STARTED</h2>
<p>There are many options available to download and install Clojure. For options other than MS Windows, please see:</p>
<ul>
<li><a href="http://clojure.org/getting_started">Clojure Getting Started</a>.</l1>
<li><a href="http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/">How to setup Clojure from scratch</a>.</l1>
</ul>
<h2><a name="labrepl">2.1 Option: Labrepl Download and Installation (for MS Windows)</a></h2>
<h3>2.1.1 What's Labrepl?</h3>
<p><span style="background-color: #FFFFCC;"><a href="http://github.com/relevance/labrepl">Labrepl</a> is an environment for exploring the Clojure language</span>. It includes:</p>
<ul>
<li>a web application that presents a set of lab exercises with step-by-step instructions</li>
<li>an interactive repl for working with the lab exercises</li>
<li>up-to-date versions of Clojure, contrib, incanter, compojure and a bunch of other libraries to explore</li>
</ul>
<p>The <a href="http://github.com/relevance/labrepl">Labrepl site</a> mentions how one can use Labrepl on other operating systems.</p>
<h3>2.1.2 Downloading and Installing Labrepl (for MS Windows)</h3>
<ul>
<li><a href="http://java.sun.com/javase/downloads/index.jsp">Download and install Java version 6</a> - this is a pre-requisite.</li>
<li>Next, go to the <a href="http://github.com/relevance/labrepl">Labrepl site</a> and click on the "<b>Download Source</b>" button on the top of the page. A .zip file will get downloaded to your computer. Extract this .zip file to your c: drive. On my computer it created a folder <b>c:\relevance-labrepl-c7d2dc1</b>.</li>
<li>For Labrepl to work we shall also need <a href="http://github.com/technomancy/leiningen">Leiningen</a>. <span style="background-color: #FFFFCC;">Leiningen is a build tool for Clojure</span>. Leiningen has experimental support for Windows and lacks the <em>self-install</em> feature. For MS Windows you need to download <b><a href="http://github.com/technomancy/leiningen/raw/master/bin/lein.bat">lein.bat</a></b> script, and put it into the folder <b>c:\leiningen</b>.</li>
<li>Set your system environment variable "<b>PATH</b>" to include the folder <b>c:\leiningen</b> (create folder, if it doesn't exist).</li>
<li>Create a sub-folder <b>c:\leiningen\lib</b>.</li>
<li>Next download <b><a href="http://github.com/downloads/technomancy/leiningen/leiningen-1.1.0-standalone.jar">leiningen-1.1.0-standalone.jar</a></b> and copy it to the folder <b>c:\leiningen\lib</b>.</li>
<li>After this, download the <a href="http://code.google.com/p/clojure/downloads/list">clojure.jar</a> package. A .zip file gets downloaded to your computer. From this .zip file extract <b>clojure.jar</b> and copy it to the <b>c:\leiningen\lib</b> folder.</li>
<li>Edit lines 14 and 15 of <b>lein.bat</b> to correct the path, namely:
<ul>
<li><b>set LEIN_JAR=c:\leiningen\lib\leiningen-1.1.0-standalone.jar</b></li>
<li><b>set CLOJURE_JAR=c:\leiningen\lib\clojure.jar</b></li>
</ul>
</li>
<li>Open a new command window and change folder to <b>c:\relevance-labrepl-c7d2dc1</b>. Next type <b>lein deps</b> to install all the dependent libraries. This might take some time.</li>
<li>Close the command window.</li>
</ul>
<h3>2.1.3 Starting the REPL</h3>
<p>Interaction with Clojure is often performed at the <b>REPL (Clojure read-eval-print loop)</b>. To start a REPL, open a new command window and change folder to <b>c:\relevance-labrepl-c7d2dc1</b>. Next type:</p>
<pre>
c:\relevance-labrepl-c7d2dc1> script\repl
</pre>
<p>This starts a new REPL session and you are presented with a simple <b>user=></b> prompt. It is at this point that REPL waits for user input. <span style="background-color: #FFFFCC;">The <b>user</b> namespace is the REPL default, like the default package in Java</span>. You should treat <b>user</b> as a scratch namespace for exploratory development.</p>
<p>After <b>user=></b> type <b>(println "Hello World")</b> and press <b>ENTER</b>:</p>
<pre>
user=> (println "Hello World")
Hello World
nil
user=>
</pre>
<p>The second line above, Hello World, is the console output you requested. The third line, <b>nil</b>, is the return value of the call to Clojure's <span style="background-color: #FFFFCC;"><b>println</b> (the funtion used to display something on the screen)</span>.</p>
<p>For a list of all the functions available in the <b>clojure.core</b> API, see - <a href="http://richhickey.github.com/clojure/clojure.core-api.html">http://richhickey.github.com/clojure/clojure.core-api.html</a>.</p>
<p>If you get your REPL into a state that confuses you, the simplest fix is to close the command window.</p>
<h3>2.1.4 Loading a file in the REPL</h3>
<p>If you have a block of code that is too large to conveniently type at the REPL, save the code into a file, and then load that file from the REPL. You can use an absolute path or a path relative to where you launched the REPL.</p>
<p>Here's how you would load a file in your REPL:</p>
<pre class="brush: clojure">
(load-file file-name)
</pre>
<p>The <b>load-file</b> function sequentially reads and evaluates the set of forms (more on this later) contained in the file.</p>
<p><span style="background-color: #FFFFCC;">A Clojure program is stored in a text file with the extension <b>.clj</b></span>. Let us load the file <b>test.clj</b> located in the folder <b>c:\users\talim\myproject\src\test</b>:</p>
<pre class="brush: clojure">
(load-file "c:/users/talim/myproject/src/test/test.clj") ; => nil
</pre>
<h2><a name="cbdw">2.2 Option: Clojure Box Download and Installation (for MS Windows)</a></h2>
<p><b>Note</b>: If you have installed Labrepl then you can ignore this step.</p>
<ol>
<li><a href="http://java.sun.com/javase/downloads/index.jsp">Download and install Java version 6</a> - this is a pre-requisite.</li>
<li>Download and install "Clojure Box". <strong><a href="http://clojure.bighugh.com/">Clojure Box</a></strong> is an all-in-one installer for Clojure on Windows. You simply install and run this one thing, and you get a <b>REPL (Clojure read-eval-print loop)</b> and all the syntax highlighting and editing goodies from clojure-mode and Slime, plus all the power of Emacs under the hood.</li>
</ol>
<p><b>Note</b>:</p>
<ul>
<li>You can watch a video of "<a href="http://vimeo.com/9219062">Install Clojure - ClojureBox</a>".</li>
<li>Read the post install notes - <a href="http://bitbucket.org/shoover/clojure-box/src/tip/post-install.txt">http://bitbucket.org/shoover/clojure-box/src/tip/post-install.txt</a>.</li>
</ul>
<h3>2.2.1 Test if Clojure Box works</h3>
<p>Interaction with Clojure is often performed at the <b>REPL</b>.</p>
<p>To test whether Clojure works, double-click on the "Clojure Box" icon on your desktop. This starts a new REPL session and you are presented with a simple <b>user=></b> prompt. It is at this point that REPL waits for user input. <span style="background-color: #FFFFCC;">The <b>user</b> namespace is the REPL default, like the default package in Java</span>. You should treat <b>user</b> as a scratch namespace for exploratory development.</p>
<p>After <b>user=></b> type <b>(println "Hello World")</b> and press <b>ENTER</b>:</p>
<pre>
user=> (println "Hello World")
Hello World
nil
user=>
</pre>
<p>The second line above, Hello World, is the console output you requested. The third line, <b>nil</b>, is the return value of the call to Clojure's <span style="background-color: #FFFFCC;"><b>println</b> (the funtion used to display something on the screen)</span>.</p>
<p>For a list of all the functions available in the <b>clojure.core</b> API, see - <a href="http://richhickey.github.com/clojure/clojure.core-api.html">http://richhickey.github.com/clojure/clojure.core-api.html</a>.</p>
<p>If you get your REPL into a state that confuses you, the simplest fix is to kill the REPL with Ctrl-C.</p>
<h3>2.2.2 Loading a file in Clojure Box</h3>
<p>If you have a block of code that is too large to conveniently type at the REPL, save the code into a file, and then load that file from the REPL. You can use an absolute path or a path relative to where you launched the REPL.</p>
<p>Here's how you would load a file in your REPL:</p>
<pre class="brush: clojure">
(load-file file-name)
</pre>
<p>The <b>load-file</b> function sequentially reads and evaluates the set of forms (more on this later) contained in the file.</p>
<p><span style="background-color: #FFFFCC;">A Clojure program is stored in a text file with the extension <b>.clj</b></span>. Let us load the file <b>test.clj</b> located in the folder <b>c:\users\talim\myproject\src\test</b>:</p>
<pre class="brush: clojure">
(load-file "c:/users/talim/myproject/src/test/test.clj") ; => nil
</pre>
<h2><a name="nbdw">2.3 Option: NetBeans/Enclojure Download and Installation (for MS Windows)</a></h2>
<p><b>Note</b>: If you have installed Labrepl or Clojure Box then you can ignore this step.</p>
<ol>
<li><a href="http://java.sun.com/javase/downloads/index.jsp">Download and install Java version 6</a> - this is a pre-requisite.</li>
<li><a href="http://netbeans.org/downloads/index.html">Download and install NetBeans 6.8</a> (Java SE option).</li>
<li><a href="http://github.com/EricThorsen/enclojure/downloads">Download the latest Enclojure .nbm file</a>.
<ul>
<li>In NetBeans go to <b>Tools > Plugins</b>. In the dialog click on <b>Downloaded</b> then click the "<b>Add Plugins...</b>" button.</li>
<li>Navigate to the location where you saved the NBM file, select it and click the "<b>Open</b>" button.</li>
<li>Highlight "<b>Clojure Plugin</b>" and click the "<b>Install</b>" button.</li>
<li>Restart the NetBeans IDE.</li>
<li>Next, navigate to <b>Tools > Options > Clojure</b> and at the bottom of the screen select <b>clojure-1.1.0</b> for the Clojure platform. Click the "<b>OK</b>" button.</li>
<li>Restart the NetBeans IDE.</li>
</ul></li>
</ol>
<h3>2.3.1 To create a Clojure Project in NetBeans</h3>
<ol>
<li>Navigate to <b>File > New Project...</b> Select <b>Categories Clojure</b> and click the "<b>Next</b>" button.</li>
<li>I created a folder <b>C:\ClojureProjects</b> on my hard disk.</li>
<li>I typed the following:
<ul>
<li>Project Name: <b>RL</b></li>
<li>Default namespace: <b>com.rl.hello</b></li>
<li>Project location: <b>C:\ClojureProjects</b></li>
</ul></li>
<li>Click the "<b>Finish</b>" button.</li>
</ol>
<h3>2.3.2 To start the REPL in NetBeans</h3>
<ol>
<li>Right click on the newly created project namely RL, which you should be seeing in the Projects window.</li>
<li>Select "<b>Start Project REPL</b>" in the window that pops up.</li>
</ol>
<h3>2.3.3 Anatomy of the Enclojure REPL Panel</h3>
<p><b>See</b>: <a href="http://www.enclojure.org/Anatomy+of+the+Enclojure+Repl+Panel">http://www.enclojure.org/Anatomy+of+the+Enclojure+Repl+Panel</a></p>
<p><b>Note</b>: You can watch a video of "<a href="http://vimeo.com/9220148">Install Clojure - NetBeans</a>".</p>
<h2><a name="syntax">2.4 Syntax</a></h2>
<p><span style="background-color: #FFFFCC;">Clojure</span> is a Lisp dialect and has a <span style="background-color: #FFFFCC;">syntax</span> that <span style="background-color: #FFFFCC;">uses parentheses and prefix notation</span>. For example, in Java one might write <b>foo(a, b, c)</b>, whereas in a Lisp dialect this becomes <b>(foo a, b, c)</b>. Since the commas are whitespace and Clojure ignores them, it can be simplified further to <b>(foo a b c)</b>. Many text editors and IDEs highlight matching parentheses, so it isn't necessary to count them in order to ensure they are balanced.</p>
<p><span style="background-color: #FFFFCC;">Clojure is case-sensitive</span>.</p>
<h2><a name="com">2.5 Comments</a></h2>
<p>Open a new REPL and try out whatever we discuss, from now on.</p>
<p>There are two ways in which you can comment in Clojure.</p>
<p>A line comment is:</p>
<pre class="brush: clojure">
; This is a single line Clojure comment
</pre>
<p>For block comments:</p>
<pre class="brush: clojure">
(comment text)
</pre>
<p>It should be noted that the block comment form above does have a return value, namely <b>nil</b>. So you can't just "comment out" a piece of your code with it, because it still leaves a trace. <span style="background-color: #FFFFCC;">This form is sometimes used at the end of a source code file</span> to demonstrate usage of an API.</p>
<p> For example, the Clojure <b>inspector</b> library ends with the following comment, demonstrating the use of the inspector:</p>
<pre class="brush: clojure">
(comment
(load-file "src/inspector.clj" )
(refer 'inspector)
(inspect-tree {:a 1 :b 2 :c [1 2 3 {:d 4 :e 5 :f [6 7 8]}]})
(inspect-table [[1 2 3][4 5 6][7 8 9][10 11 12]])
)
</pre>
<h2><a name="ccg">2.6 Clojure Coding Guidelines & Naming Convention</a></h2>
<ol>
<li>Use two spaces for indentation.</li>
<li>Make your names for functions, <b>vars</b> as descriptive as possible, without being overly verbose.</li>
<li>Use lower-case letters for names.</li>
<li>The names of predicate functions (returning a truthy (everything not <b>nil</b> or <b>false</b>) or falsy (<b>false</b> and <b>nil</b>) should typically end with a question mark (?).</li>
<li>End the name of a function in an exclamation mark (!) if it is destructive.</li>
</ol>
<p>The obvious exceptions to the guidelines above are when generating Java code, which requires that Java naming conventions be observed.</p>
<p>For more details please see the <a href="http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards">Clojure Library Coding Standards</a>.</p>
<p>The naming convention in Clojure is to <span style="background-color: #FFFFCC;">use all lowercase with hyphens separating words in multi-word names</span>, unlike the Java convention of using camelcase.</p>
<p><b>An example</b>:</p>
<pre class="brush: clojure">
(function-name arg1 arg2 arg3)
</pre>
<h2><a name="forms">2.7 Forms</a></h2>
<p> Clojure code is composed of Clojure data. When you run a Clojure program, a part of Clojure called the reader reads the text of the program in chunks called forms and translates them into Clojure data structures. Clojure then compiles and executes the data structures.</p>
<p>A Clojure form is basically just an expression. It's any piece of code that evaluates down to a single value.</p>
<p><span style="background-color: #FFFFCC;">The Clojure <b>forms</b> are: symbols, literals (i.e. booleans, nil, numbers, characters, strings, keywords), lists, vectors, maps and sets</span>.</p>
<h2><a name="symbols">2.8 Symbols</a></h2>
<p><span style="background-color: #FFFFCC;">Symbols are used to name things</span>. Symbols name all sorts of things in Clojure:</p>
<ul>
<li>Functions like <b>str</b> and <b>concat</b></li>
<li><span style="background-color: #FFFFCC;">Clojure does not have operators</span>. Characters like + - * / are just functions</li>
<li>Java classes like <b>java.lang.String</b> and <b>java.util.Random</b></li>
<li>Namespaces like <b>clojure.core</b> and Java packages like <b>java.lang</b></li>
<li>Data structures and references.</li>
</ul>
<p>Symbols <em>cannot</em> start with a number and can consist of alphanumeric characters, plus +, -, *, /, !, ?, ., and _.</p>
<p>You can call a function through a symbol such as <b>println</b>:</p>
<pre class="brush: clojure">
(println "Hello Clojure participants") ; => Hello Clojure participants
</pre>
<p>Rather than calling a function through a symbol, you might choose just to retrieve the function itself. The literal representation of a function at the REPL is just a mangled name:</p>
<pre class="brush: clojure">
println
</pre>
<p>Sometimes you want to refer to the symbol itself, without retrieving whatever it refers to. To do this, you can quote the symbol:</p>
<pre class="brush: clojure">
(quote println) ; => println
</pre>
<p>Quoting is so common that that there is a sugared form: simply put a single quote in front of any symbol to prevent that form from being evaluated:</p>
<pre class="brush: clojure">
'println ; => println
</pre>
<h2><a name="vandb">2.9 Vars and Bindings</a></h2>
<p>The <span style="background-color: #FFFFCC;">special form (these are forms evaluated in a special way)</span> <b>def</b> creates a <b>var</b>. If the <b>var</b> did not already exist and no initial value is supplied, the <b>var</b> is unbound. In the code below, x is a symbol which is used to identify the <b>var</b> in the future. At this point, x has no "value", and so we can't refer to it:</p>
<pre class="brush: clojure">
(def x) ; => #'user/x
x ; => java.lang.IllegalStateException: <b>var</b> user/x is unbound.
</pre>
<p>If called with an additional parameter it creates a root binding or rebinds the <b>var</b> in case it was already bound. This binding is like an "invisible" link between the <b>var</b> and the value. For example, the following <b>def</b> creates a <b>var</b> named user/my-var in the namespace user:</p>
<pre class="brush: clojure">
(def my-var 10) ; => #'user/my-var
</pre>
<p><span style="background-color: #FFFFCC;">The symbol user/my-var refers to a <b>var</b> that is bound to the value 10. The initial value of a <b>var</b> is called its <em>root binding</em></span>.</p>
<p>Clojure provides bindings which are like constants in other languages, which are not intended to be changed after a value is assigned. Other threads can then override that binding temporarily. Threads which do not have a thread local binding will inherit the root binding. There are global bindings, thread-local bindings, bindings that are local to a function and bindings that are local to a given form.</p>
<p>The <b>def</b> special form creates a global binding and optionally gives it a "root value" that is visible in all threads unless a thread-local value is assigned.</p>
<p>In Clojure, the object that your <b>var</b> is referring to can't change. If you want your <b>var</b> to refer to a different value, you have to rebind it to a new object, a new value. Although vars can be rebound, it is generally not done in a program except to create thread-local bindings.</p>
<h2><a name="literals">2.10 Literals</a></h2>
<h3>2.10.1 Booleans and nil</h3>
<p>Clojure’s rules for booleans (<b>true</b> and <b>false</b>) are easy to understand:</p>
<ol>
<li><b>true</b> is <b>true</b>, and <b>false</b> is <b>false</b>.</li>
<li>In addition to <b>false</b>, <b>nil</b> (meaning 'nothing/no-value'- represents Java <b>null</b>) also evaluates to <b>false</b> when used in a boolean context.</li>
<li><span style="background-color: #FFFFCC;">Other than <b>false</b> and <b>nil</b>, everything else evaluates to <b>true</b> in a boolean context</span>.</li>
</ol>
<h3>2.10.2 Numbers</h3>
<p>A number consists of only the digits 0-9, a decimal point '.', a sign ('+' or '-'), and an optional 'e' for numbers written in exponential notation. In addition to these elements, numbers in Clojure can take either octal or hexadecimal form and also include an optional 'M' (this is used to explicitly create a <b>BigDecimal</b>).</p>
<p>Clojure supports the following numeric types: integer, floating point, ratio.</p>
<p>Integers comprise the whole number set, both positive and negative. That is, any number starting with an optional sign or digit followed exclusively by digits is considered and stored as an integer. Integers in Clojure can theoretically take an infinitely large value, although in practice the size is limited by the memory available.</p>
<p>Floating point numbers are of the form of some number of digits, a decimal point, followed by some number of digits. However, floating point numbers can also take an exponential form where a significant part is followed by an exponent part separated by a lower or uppercase 'E'.</p>
<pre class="brush: clojure">
0x7F ; => hexadecimal number whose value is 127
0177 ; => octal number whose value is 127
11.7e-3 ; => 0.0117
(+ 1 2 3 4) ; => 10
(/ 22 7) ; => 22/7
200/5 ; => 40
</pre>
<p>In the code above, we first use the + function to add the numbers 1, 2, 3 and 4. The result of <b>(/ 22 7)</b> can be surprising - Clojure has a built in <b>clojure.lang.Ratio</b> type. Using ratios help avoid inaccuracies in long computations. Ratios are represented by an integer numerator and denominator. Also observe that the ratio 200 / 5 will resolve to the integer 40.</p>
<p>Lets first try a computation of (1/5 * 5/1) as floating point. Later we try the same with Ratio.</p>
<pre class="brush: clojure">
(def x (/ 1.0 5.0))
(def y (/ 5.0 1.0))
(* x y) ; => 1.0
(def p (* x x x x x x x x x x))
(def q (* y y y y y y y y y y))
(* p q) ; => 1.0000000000000004
</pre>
<p>The value of (* p q) above is 1.0000000000000004 instead of 1 which is what we want. This is due to the inaccuracies of x and y multiplying as we create p and q. You really don't want such calculations happening in your financial transactions!</p>
<p>The same done with ratios below:</p>
<pre class="brush: clojure">
(def x (/ 1 5))
(def y (/ 5 1))
(* x y) ; => 1
(def p (* x x x x x x x x x x))
(def q (* y y y y y y y y y y))
(* p q) ; => 1
</pre>
<p>Using a floating point literal instead, we get:</p>
<pre class="brush: clojure">
(/ 22.0 7) ; => 3.142857142857143
</pre>
<h4>2.10.2.1 Arbitrary-precision arithmetic <img src="http://rubylearning.com/images/coffee_cup.gif" alt="Java" /></h4>
<p>In Clojure, we can do <b><a href="http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic">arbitrary-precision arithmetic</a></b> - a technique whereby calculations are performed on numbers whose digits of precision are limited only by the available memory of the host system. Clojure relies on Java's <b>BigDecimal</b> class for arbitrary-precision decimal numbers and on Java's <b>BigInteger</b> class for arbitrary-precision integers.</p>
<p>If you are doing arbitrary-precision math, append M to a number to create a <b>BigDecimal</b> literal:</p>
<pre class="brush: clojure">
(+ 1 (/ 0.00001 1000000000000000000)) ; => 1.0
(+ 1 (/ 0.00001M 1000000000000000000)) ; => 1.00000000000000000000001M
</pre>
<p><span style="background-color: #FFFFCC;">Clojure objects are Java objects</span> and you can use Java's Reflection API methods such as <b>class</b>, <b>ancestors</b>, and <b>instance?</b> to reflect against the underlying Java object model.</p>
<pre class="brush: clojure">
(class (+ 1 (/ 0.00001M 1000000000000000000))) ; => java.math.BigDecimal
</pre>
<p>Clojure's approach to arbitrary-sized integers is simple: just don't worry about it. Clojure will automatically upgrade to <b>Long</b> or <b>BigInteger</b> when you need it. Try creating some small and large integers, and then inspect their class:</p>
<pre class="brush: clojure">
(class (* 100 100 100)) ; => java.lang.Integer
(class (* 9000 9000 9000)) ; => java.lang.Long
(class (* 9000 9000 9000 9000 9000 9000 9000 9000)) ; => java.math.BigInteger
</pre>
<h4>2.10.2.2 format</h4>
<p>Round off a number to say 2 decimal places:</p>
<pre class="brush: clojure">
(format "%.2f" 1.2345) ; => "1.23"
</pre>
<h3>2.10.3 Characters and Strings</h3>
<p>Clojure character literals are preceded by a backslash. Their literal syntax is \{letter}, where letter can be a letter or the name of a character: backspace, form-feed, newline, return, space, or tab. These yield the corresponding characters.</p>
<p><span style="background-color: #FFFFCC;">Clojure strings are Java strings</span>. They are immutable, and have access to all the underlying Java methods. They are delimited by double quotes ("), and they can span multiple lines. Strings are sequences of characters. The function <b>concat</b> returns a list of character literals, of the elements in the supplied strings:</p>
<pre class="brush: clojure">
(concat "Hello" " World") ; => (\H \e \l \l \o \space \W \o \r \l \d)
</pre>
<p><span style="background-color: #FFFFCC;">Clojure's <b>str</b> is a function call that concatenates an arbitrary list of arguments into a string</span>:</p>
<pre class="brush: clojure">
(str \h \e \l \l \o \space \w \o \r \l \d) ; => "hello world"
(str "Hello" " " "World") ; => "Hello World"
</pre>
<p>Standard Java escape characters are supported. If you want to put a double quote inside a string then you have to escape the double quote. <span style="background-color: #FFFFCC;">The backslash is the escape character</span>:</p>
<pre class="brush: clojure">
(println "She replied: \"Hello\" to my greetings.") ; => She replied: "Hello" to my greetings.
</pre>
<h3>2.10.4 Keywords</h3>
<p><span style="background-color: #FFFFCC;">A keyword is like a symbol, except that keywords begin with a colon (:)</span>. Keywords resolve to themselves:</p>
<pre class="brush: clojure">
:foo ; => :foo
</pre>
<p>The fact that keywords resolve to themselves makes keywords useful as keys.</p>
<h2><a name="ex110">2.11 Exercises</a></h2>
<h3>2.11.1 Exercise 1</h3>
<p>Write a Clojure program that displays how old I am, if I am 979000000 seconds old.</p>
<p><b>Sample solution</b>:</p>
<pre class="brush: clojure">
(println "You are" (/ 979000000 60.0 60 24 365) "years old") ; => You are 31.04388635210553 years old
; Note that println automatically added a space between its arguments
</pre>
<p>We can improve upon the above program. It's always better to perform the calculation using exact numbers and then coerce the result if needed (we use <b>float</b> in the example below). This is an advantage which Clojure offers when compared to other languages; you can perform calculations with exact numbers instead of floating point approximations. A better solution would be:</p>
<pre class="brush: clojure">
(println "You are" (float (/ 979000000 60 60 24 365)) "years old") ; => You are 31.043886 years old
</pre>
<h3>2.11.2 Exercise 2</h3>
<p>Write a Clojure program that tells you how many minutes there are in a year (do not bother right now about leap years etc.).</p>
<p><b>Sample solution</b>:</p>
<pre class="brush: clojure">
(println "There are" (* 60 24 365) "minutes in a year") ; => There are 525600 minutes in a year
</pre>
<h2>3.0 CHARGING AHEAD</h2>
<h2><a name="collect">3.1 A Quick look at Collections</a></h2>
<p>Clojure provides the collection types list, vector, set and map. <span style="background-color: #FFFFCC;">The Clojure collection types are immutable, heterogeneous and persistent</span>. By <span style="background-color: #FFFFCC;">immutable</span> it means that their contents cannot be changed. By <span style="background-color: #FFFFCC;">heterogeneous</span> it means that they <span style="background-color: #FFFFCC;">can hold any kind of object</span>. Bt <span style="background-color: #FFFFCC;">persistent</span> it means that when a new version of a collection is created by adding or removing something from it, <span style="background-color: #FFFFCC;">the new version shares structure with the old one</span>. The old version will be accessible only when we hold a reference to its head otherwise it will be garbage collected.</p>
<h3>3.1.1 Lists</h3>
<p>Lists are written with parenthesis. Lists are the traditional LISP singly linked lists. Lists can contain items of any type, including other collections:</p>
<pre class="brush: clojure">
; Empty list
() ; => ()
(class ()) ; => clojure.lang.PersistentList$EmptyList
'(a b c) ; => (a b c)
(class '(a b c)) ; => clojure.lang.PersistentList
</pre>
<p>A list is "just data," but it is also used to call functions. They are ideal when new items will be added to or removed from the front. <span style="background-color: #FFFFCC;">Lists are not efficient for finding items by index</span>.</p>
<p>An example of a list whose first item names a Clojure function:</p>
<pre class="brush: clojure">
(+ 1 2)
</pre>
<p><span style="background-color: #FFFFCC;">In Clojure, data and code have the same representation. <b>(a b c)</b> is a call to a function named a with arguments b and c. To make this data instead of code, the list needs to be quoted. <b>'(a b c)</b> or <b>(quote (a b c))</b> is a list of the values a, b and c</span>.</p>
<h3>3.1.2 Vectors</h3>
<p>Vectors are essentially like dynamically-sized arrays. Vectors store a series of values like lists do and can be used like lists, except that they can be indexed by integers. Vectors are written with square brackets:</p>
<pre class="brush: clojure">
[1 2 3] ; => [1 2 3]
(class [1 2 3]) ; => clojure.lang.PersistentVector
[ ] ; => [ ]
(class [ ]) ; => clojure.lang.PersistentVector
</pre>
<p>Vectors are ideal when new items will be added to or removed from the back. <span style="background-color: #FFFFCC;">Vectors are efficient for finding or changing items by index</span> i.e. vectors are functions of their indices:</p>
<pre class="brush: clojure">
; retrieve an element by its index
(["hello" "world" 1 2 3] 1) ; => "world"
</pre>
<p><b>Note</b>: Unless the list characteristic of being more efficient at adding to or removing from the front is significant for a given use, <span style="background-color: #FFFFCC;">vectors are typically preferred over lists</span>. This is mainly due to the vector syntax of [...] being a bit more appealing than the list syntax of '(...). It doesn't have the possibility of being confused with a call to a function, macro or special form.</p>
<h3>3.1.3 Sets</h3>
<p>Sets are collections of <em>unique</em> items. Sets are zero or more forms enclosed in braces preceded by #. The #{} reader macro is only for hash sets:</p>
<pre class="brush: clojure">
#{ } ; => #{ }
(class #{ }) ; => clojure.lang.PersistentHashSet
#{:a :b :c} ; => #{:a :b :c}
</pre>
<p><span style="background-color: #FFFFCC;">Sets are preferred over lists and vectors when duplicates are not allowed and items do not need to be maintained in the order in which they were added</span>. Clojure supports two kinds of sets, unsorted and sorted. Hash sets are generally preferred over sorted sets as they are much faster. Sorted sets are important when keeping things sorted is very important. Here are some more ways to create a set:</p>
<pre class="brush: clojure">
(sorted-set "Mandy" "Anita" "Rich") ; #{"Anita" "Mandy" "Rich"}
(hash-set "Mandy" "Anita" "Rich") ; #{"Anita" "Mandy" "Rich"}
; duplicates are removed
(hash-set "Rich" "Mandy" "Anita" "Rich") ; #{"Anita" "Mandy" "Rich"}
</pre>
<h3>3.1.4 Maps</h3>
<p><span style="background-color: #FFFFCC;">Maps are zero or more key/value pairs where both can be any kind of object and enclosed in braces</span>. Maps store unique keys and one value per key. Often keywords are used for map keys:</p>
<pre class="brush: clojure">
{ } ; => { }
(class { }) ; => clojure.lang.PersistentArrayMap
{:Ruby "Matz" :Clojure "Hickey"} ; => {:Ruby "Matz" :Clojure "Hickey"}
</pre>
<p>You can use a map directly, it is not necessary to bind it to a name:</p>
<pre class="brush: clojure">
(:a {:a 1, :b 2}) ; => 1
</pre>
<p>We can use <b>def</b> to save the map into a Clojure <b>var</b>:</p>
<pre class="brush: clojure">
(def inventors {:Ruby "Matz" :Clojure "Hickey"})
</pre>
<p>Commas are considered whitespace, and can be used to separate the pairs:</p>
<pre class="brush: clojure">
(def inventors {:Ruby "Matz", :Clojure "Hickey"})
</pre>
<p>Maps are functions. If you pass a key to a map, it will return that key’s value, or it will return <b>nil</b> if the key is not found:</p>
<pre class="brush: clojure">
(:Clojure inventors) ; => Hickey
(inventors :Java) ; => nil
</pre>
<p>The <b>keys</b> function returns a sequence of the map's keys:</p>
<pre class="brush: clojure">
; Usage: (keys map)
(keys inventors) ; => (:Ruby :Clojure)
</pre>
<p>The <b>vals</b> function returns a sequence of the map's values:</p>
<pre class="brush: clojure">
; Usage: (vals map)
(vals inventors) ; => ("Matz" "Hickey")
</pre>
<h3>3.1.5 Some functions on collections</h3>
<p>There are many core functions that operate on all kinds of collections; far too many to describe here. A small subset of them is described next, mostly using vectors and sometimes lists.</p>
<h4>3.1.5.1 count function</h4>
<p>The <b>count</b> function returns the number of items in any collection.</p>
<pre class="brush: clojure">
(count [22 "green" false]) ; => 3
; empty collections correctly return 0
(count '()) ; => 0
</pre>
<h4>3.1.5.2 reverse function</h4>
<p>The <b>reverse</b> function returns a sequence of the items in the collection in reverse order.</p>
<pre class="brush: clojure">
(reverse [2 42 72]) ; => (72 42 2)
(reverse '(2 42 72)) ; => (72 42 2)
; strings are collections too
(reverse "hello") ; => (\o \l \l \e \h)
</pre>
<h4>3.1.5.3 apply function</h4>
<p>The <b>apply</b> function returns the result of a given function when all the items in a given collection are used as arguments.</p>
<pre class="brush: clojure">
(apply - [34 23 9]) ; => 2
</pre>
<h4>3.1.5.4 map function</h4>
<pre class="brush: clojure">
(map f coll)
</pre>
<p><b>map</b> takes a source collection coll and a function f, and it returns a new sequence by <em>invoking f on each element in the coll</em>.</p>
<pre class="brush: clojure">
(map * [1 2 3 4] [1 2 3 4]) ; => (1 4 9 16)
</pre>
<h2><a name="seq">3.2 Sequences</a></h2>
<p>A <b>sequential collection</b> is one that holds a series of values without reordering them.</p>
<p>A <b>sequence</b> is a sequential collection that represents a series of values that may or may not exist yet. They may be values from a concrete collection, or values that are computed as necessary. <em>A sequence may be empty</em>.</p>
<p><span style="background-color: #FFFFCC;">Sequences include Java collections, Clojure-specific collections, strings, streams, directory structures and XML trees</span>. Because so many things are sequences, the sequence library is very powerful. Remember that <span style="background-color: #FFFFCC;">the sequence library can be used with all collections (lists, vectors, sets, maps ...)</span>.</p>
<p><span style="background-color: #FFFFCC;"><b>Important</b>: Most Clojure sequences are <em>lazy</em> i.e. they generate elements only when they are actually needed. Clojure sequences are <em>immutable</em>: they never change</span>.</p>
<h3>3.2.1 seq</h3>
<p>The <b>seq</b> function turns any core collections into something called a <b>seq</b> i.e. the <b>seq</b> function will return a <b>seq</b> on any seq-able collection (<b>coll</b>):</p>
<pre class="brush: clojure">
(seq coll)
</pre>
<p><b>seq</b> will return <b>nil</b> if its <b>coll</b> is empty or nil.</p>
<p><b>An example</b>:</p>
<pre class="brush: clojure">
(seq [1 2 3]) ; => (1 2 3)
(seq [ ]) ; => nil
</pre>
<h3>3.2.2 first</h3>
<p>You can get the first item in a sequence:</p>
<pre class="brush: clojure">
(first aseq)
</pre>
<p><b>first</b> returns <b>nil</b> if its argument is empty or nil.</p>
<p><b>An example</b>:</p>
<pre class="brush: clojure">
(first [34 23 15]) ; => 34
(first [ ]) ; => nil
</pre>
<h3>3.2.3 rest</h3>
<p>You can get everything after the first item, in other words, the rest of a sequence:</p>
<pre class="brush: clojure">
(rest aseq)
</pre>
<p><b>rest</b> returns an empty seq (not <b>nil</b>) if there are no more items.</p>
<p><b>An example</b>:</p>
<pre class="brush: clojure">
(rest [34 23 15]) ; => (23 15)
(rest [ ]) ; => ()
(class (rest [ ])) ; => clojure.lang.PersistentList$EmptyList
</pre>
<h3>3.2.4 cons</h3>
<p>You can construct a new sequence by adding an item to the front of an existing sequence:</p>
<pre class="brush: clojure">
(cons elem aseq)
</pre>
<p><b>An example</b>:</p>
<pre class="brush: clojure">
(cons 1 [2 3 4]) ; => (1 2 3 4)
</pre>
<p>Under the hood, <b>first</b>, <b>rest</b> and <b>cons</b> are declared in a Java interface <b>clojure.lang.ISeq</b>.</p>
<h3>3.2.5 next</h3>
<p>The <b>next</b> function will return the seq of items after the first:</p>
<pre class="brush: clojure">
(next aseq)
</pre>
<p><b>(next aseq)</b> is equivalent to <b>(seq (rest aseq))</b>.</p>
<p><b>Examples</b>:</p>
<pre class="brush: clojure">
(next [1 2 3 4]) ; => (2 3 4)
(next [ ]) ; => nil
</pre>
<h3>3.2.6 conj, into</h3>
<pre class="brush: clojure">
(conj coll element & elements)
(into to-coll from-coll)
</pre>
<p><b>conj</b> adds one or more elements to a collection, and <b>into</b> adds all the items in one collection to another. For lists, <b>conj</b> and <b>into</b> add to the front:</p>
<pre class="brush: clojure">
(conj '(10 20 30) :a) ; => (:a 10 20 30)
(into '(10 20 30) '(:a :b :c)) ; => (:c :b :a 10 20 30)
</pre>
<p>For vectors, <b>conj</b> and <b>into</b> add elements to the back:</p>
<pre class="brush: clojure">
(conj [10 20 30] :a) ; => [10 20 30 :a]
(into [10 20 30] [:a :b :c]) ; => [10 20 30 :a :b :c]
</pre>
<h3>3.2.7 range</h3>
<p><b>range</b> produces a sequence from a start to an end, incrementing by step each time. Ranges include their start, but not their end. If you do not specify them, start defaults to zero, and step defaults to 1.</p>
<pre class="brush: clojure">
(range 10 20 2) ; => (10 12 14 16 18)
</pre>
<h3>3.2.8 repeat</h3>
<p>The <b>repeat</b> function repeats an element p n times:</p>
<pre class="brush: clojure">
(repeat 5 "p") ; => ("p" "p" "p" "p" "p")
</pre>
<h3>3.2.9 iterate, take</h3>
<pre class="brush: clojure">
(iterate f x)
</pre>
<p><b>iterate</b> begins with a value x and continues forever, applying a function f to each value to calculate the next.</p>
<p>If you begin with 1 and iterate with <b>inc</b>, you can generate the whole numbers:</p>
<pre class="brush: clojure">
(take 10 (iterate inc 1)) ; => (1 2 3 4 5 6 7 8 9 10)
</pre>
<p>Since the sequence is infinite, you need another new function to help you view the sequence from the REPL.</p>
<pre class="brush: clojure">
(take n sequence)
</pre>
<p><b>take</b> returns a lazy sequence of the first n items from a collection and provides one way to create a finite view onto an infinite collection.</p>
<p>The following example creates a lazy seq of all natural numbers:</p>
<pre class="brush: clojure">
(def natural-numbers (iterate inc 0))
</pre>
<p>An usage example:</p>
<pre class="brush: clojure">
(take 5 natural-numbers) ; => (0 1 2 3 4)
</pre>
<h3>3.2.10 concat</h3>
<p>The <b>concat</b> function can be used for plain concatenation of any collection:</p>
<pre class="brush: clojure">
(concat [22 "green" false] [33 44]) ; => (22 "green" false 33 44)
; the two collections can be of different types
(concat #{22 "green" false} '(33 44)) ; => ("green" false 22 33 44)
</pre>
<h2><a name="fc">3.3 Flow Control</a></h2>
<h3>3.3.1 if, if-not</h3>
<p>Clojure’s <b>if</b> evaluates its first argument. If the argument is logically true, it returns the result of evaluating its second argument. If you want to define a result for the "else" part of if, add it as a third argument (but this is optional):</p>
<pre class="brush: clojure">
(println (if (< 34 100) "yes" ))
; => yes
(println (if 0 "Zero is true" "Zero is false")) ; => Zero is true
</pre>
<p>If the first argument to <b>if</b> is logically false and you didn't specify an else form, it returns <b>nil</b>:</p>
<pre class="brush: clojure">
(if (< 50000 100) "yes" )
; => nil
</pre>
<p>The <b>if-not</b> macro does the inverse of what the <b>if</b> special form does. The general structure of this macro is:</p>
<pre class="brush: clojure">
(if-not test consequent alternative?)
</pre>
<p>Here, if the test is false, the consequent is evaluated, else if it is true and the alternative is provided, it is evaluated instead.</p>
<h3>3.3.2 cond, condp</h3>
<p><b>cond</b> is like the case statement of Clojure. The general form looks like the following:</p>
<pre class="brush: clojure">
(cond & clauses)
</pre>
<p>Here's an example:</p>
<pre class="brush: clojure">
(def x 10)
(cond
(< x 0) (println "Negative!")
(= x 0) (println "Zero!"))
; => nil
(cond
(< x 0) (println "Negative!")
(= x 0) (println "Zero!")
:default (println "Positive!"))
; => Positive!
</pre>
<p>As you can see, the clauses are a pair of expressions, each of the form <em>test consequent</em>. Each test expression is evaluated in sequence, and when one returns true, the associated consequent is evaluated and returned. If none return true, <b>nil</b> is returned. If a <b>:default</b> is provided, the associated consequent is evaluated and returned instead.</p>
<p>The general form of <b>condp</b> looks like the following:</p>
<pre class="brush: clojure">
(condp pred expr & clauses)
</pre>
<p><span style="background-color: #FFFFCC;">The <b>condp</b> macro is similar to a case statement in other languages</span>. It takes a two parameter predicate (this is mostly <b>=</b> or <b>instance?</b>) and an expression to act as its second argument. After those it takes any number of value/result expression pairs that are evaluated in order. If the predicate evaluates to <b>true</b> when one of the values is used as its first argument then the corresponding result is returned. An optional final argument is the result to be returned if no given value causes the predicate to evaluate to true. If this is omitted and no given value causes the predicate to evaluate to true then an <b>IllegalArgumentException</b> is thrown:</p>
<pre class="brush: clojure">
(condp = 1
1 "Clojure"
2 "Ruby"
3 "Java"
"Sorry, no match")
; => "Clojure"
(condp = 5
1 "Clojure"
2 "Ruby"
3 "Java"
"Sorry, no match")
; => "Sorry, no match"
</pre>
<h3>3.3.3 when, when-not</h3>
<p>The <b>when</b> form is similar to the <b>if</b> form. The differences are that there is no "else" condition, and more than one expression can be added to the <b>when</b> form for evaluation when the condition is true.</p>
<pre class="brush: clojure">
(when true "do-this-first" "then-that" "finally this") ; => "finally this"
</pre>
<p><b>when-not</b> is the opposite of <b>when</b>, in that it evaluates its body if the test returns false.</p>
<pre class="brush: clojure">
(when-not true "do-this-first" "then-that" "finally this") ; => nil
(when-not false "do-this-first" "then-that" "finally this") ; => "finally this"
</pre>
<h3>3.3.4 do</h3>
<p>The <b>do</b> form is used to execute a number of operations in sequence. Clojure provides the <b>println</b> form for writing to standard output. In order to use <b>println</b> within an expression whose return value we care about, we need to put it in a <b>do</b> expression:</p>
<pre class="brush: clojure">
(do (println "Hello.") (+ 2 2))
Hello.
4
(do (println "Hello.") (println "Hello again.") (+ 2 2))
Hello.
Hello again.
4
</pre>
<p>The <b>do</b> operation executes each expression in sequence and returns the result of the last expression.</p>
<p><b>do</b> is useful when you want to include a sequence of actions in a position where only a single form is expected, e.g. for having various statements in a branch of an <b>if</b>.</p>
<p>Here's a contrived example:</p>
<pre class="brush: clojure">
(if (odd? 3) (println "First true form") (println "Second true form (will not print)")) ; => First true form
(if (odd? 3) (do (println "First true form") (println "Second true form (will print)")))
; => First true form
; => Second true form (will print)
</pre>
<p><b>if</b> only accepts one form as <b>if</b> and <b>else</b> branch, so if you want to have several statements in either, you'll have to wrap them in a <b>do</b>. In the first statement above, the second true from will not print, since Clojure sees it as the else-branch. In the second it prints, because <b>do</b> is considered one form.</p>
<h2><a name="defunc">3.4 Defining Functions</a></h2>
<p>The <b>defn</b> macro defines a function. Its arguments are the function name, an optional documentation string, the parameter list (specified with a vector that can be empty) and the function body. The result of the last expression in the body is returned. Every function returns a value, but it may be <b>nil</b>.</p>
<pre class="brush: clojure">
(defn my-function
"returns a String"
[name]
(str "Goodbye, " name)) ; concatenation