I love reading books and I love learning programming languages, but I’ve found that I don’t like reading books to learning programming languages. This is especially true for some of the new languages, specifically Scala and Clojure. Yes you can read a multitude of acronym vebosities as an author tries and shows you just how many words they can type to help explain a feature, but I would rather just have the core basics, explained via lots of examples.
If you have read any of the the Little Schemer books, which are just a set of examples getting increasingly more complex, or have checked out any of the learnxinyminutes.com pages, then you will find this article ( and the subsequent ones ), very similar. I found I learn by example, and as I learn a new language I write down examples of each of the features as I learn them.
These notes are how I learnt Clojure and built my first apps with it.
First lets get some basic terminology out of the way, specifically atoms, s-expressions and forms. In Clojure code is made up of s-expressions, and s-expressions are recursively made up of either an s-expression or an atom
An atom is the most basic of types, an immutable object that always resolves to itself, typically a scala type such as an integer, float, string or char
1 ;; Integer atom 2.3 ;; Float atom "keith" ;; String atom \b ;; Char atom
An s-expressions is sequence of data surrounded by parantheses that is evaluated by the Clojure interpreter. For a generic definition see Wikipedia, which states
In computing, s-expressions, sexprs or sexps (for “symbolic expression”) are a notation for nested list (tree-structured) data, invented for and popularized by the programming language Lisp, which uses them for source code as well as data.
And from Clojure.org itself, they are defined as:
Clojure programs are composed of expressions. Every form not handled specially by a special form or macro is considered by the compiler to be an expression, which is evaluated to yield a value. There are no declarations or statements, although sometimes expressions may be evaluated for their side-effects and their values ignored.
Clojure works by taking an s-expressions, a list of data surrounded by () and assumes the first element in the list is a function. It then applies the function the remaining items of data in the list. In Clojure this is called a form. The only deviation from this rule is for either special forms and macros, both we’ll talk about later as we come across them and now neccassary at this stage
; This is a comment, in Clojure all single line comments start with a ';' ;; However the Clojure community seems to prefer the use of double ';;' instead ;;; However this is a comment ;;;; And so is this ;;;;;;;;; Clojure basically ignores everything after the first ; ;; For more details on a community attempt to document Clojure code, head over ;; to https://clojuredocs.org/ ;; There are other ways to comments code out and we'll come across that as we ;; move through this tutorial ;; Before you can even start using Clojure you need to get an instance running ;; Clojure runs on top of the Java virtual machine, so first you need to install ;; an appropriate JVM. ;; This can be downloaded from Oracle https://www.java.com/en/download/ ;; Clojure needs atleast Java 6 SDK to run ;; Once installed and running you then need to download the latest Clojure from ;; http://clojure.org/downloads ;; The first way we will use Clojure is through the native REPL, which stands for ;; Read, Evalutate, Print, Loop ;; This provides a command line interface that you can execute Clojure commands from ;; To run the REPL, execute the following command from the command line ;; java -cp /Clojure-1.6.0/clojure-1.6.0.jar clojure.main ; Get Help ;; Before we get started you are going to want more help that these files produce ;; The primary source of all Clojure info is at ;; http://clojure.org/ ;; This tutorial is heavily based on the learn x in y minutes pages at ;; http://learnxinyminutes.com/docs/clojure/ ;; The primary difference being its structure the way I think and learnt Clojure ;; which builds from first principles as a pure Lisp language and then introduces ;; the additional complexity added by he Java Virtual Machine ;; When you really just need help on syntax, or just need to remember the name ;; of a command then your first stop should be ;; http://clojure.org/cheatsheet ; Getting started ;; Clojure is a Lisp, a member of a family of languages, including Scheme, Common Lisp ;; Lisp ( and therefore Clojure ) are built around the basic concept of a list of things ;; more commonly called forms ;; Forms are bounded by brackets either () or  and contain zero or more items which ;; make up the list ;; Typically Clojure ( and all Lisps ) assume that the first element of a list is a ;; function call, and all other elements are parameters which are passed to the ;; function ;; The most basic of functions are the basic arithmetic, + - * /, e.g (+ 2 2) ;; Add 2 and 2, returning 4 (* 1 2 3) ;; Multiple 1, 2 and 3, returning 6 ;; If you don't want Clojure to interpret your form, then you can quote it with either the ;; character ' or the function 'quote' '(+ 2 2) ;; All elements of the form are taken as a list ;; In this instance creates a list of 3 items (quote (+ 2 2)) ;; Identical to the above ;; If we want to evaluate a list of elements, we can use the function 'eval' (eval '(+ 2 2)) ;; Returns the value 4 ;; The examples for quote and eval above show the use of nested lists ;; Each element of a list can be an individual item or a list itself ;; Lists are evaluated to a single item as the list is interpreted (+ (* 2 3) (* 4 2)) ;; Becomes (+ 6 8) ;; Which becomes 14 ;; There is not limited to the depth of nesting in Lisp (+ (+ (+ 2 2 ) 3) 4) ;; Whitespace and commas ;; Its worth exploring how Clojure ( and Lisp ) uses whitespace to separate ;; elements of the list, and how commas ',' can be used to show individual ;; items but are ignore by the interpreter ;; Maths Operators (+ 2 2) (- 1 2) (* 2 3) (/ 4 2) (quot 3 2) ;; quot[ient] of dividing numerator by denominator. Returns 1 (rem 3 2) ;; remainder of dividing numerator by denominator (mod 2 3) ;; Modulus of num and div (inc 2) ;; Increments the number by 1 (dec 3) ;; Decrements the number by 1 (max 3 5 7) ;; Maximum number in list (min 2 4 1 7) ;; Minimum number in list ;; Boolean operations ;; In Clojure, boolean True is represented as true and boolean False as false ;; Everything except `false' and `nil' is true in boolean context. ;; In Clojure nil means 'nothing', and is not the same as (), the empty set ;; Comparison operators ;;; = ;; Compares if the 2 elements are the same and the same value (= 2 2) ;; true (= 2 2.0) ;; false ;;; == ;; Compares the numeric value, true if equals (= 2 2) ;; true (= 2 2.0) ;; true (not= 2 3) ;; Not equal to each other (< 1 2 3) ;; Tests first element is less than all others (> 2 3 4) ;; Tests first element is less than all others (<= 4 4) ;; Tests first element is less than or equal to all others (>= 6 5 5) ;; Tests first element is great than or equal to all others (compare 3 4) ;; Returns a negative number, zero, or a positive number ;; when x is logically 'less than', 'equal to', ;; or 'greater than' y ;; Tests. Unary methods that test the value of a result. Return true or false (zero? 1) ;; Is the number 0, true or false (pos? -1) ;; Is the number postive, true or false (neg? 1) ;; Is the number negative, true or false (even? 2) ;; Is the number even, true or false (odd? 3) ;; Is the number odd, true or false (number? 'hello') ;; Is the number a number, true or false (rational? 1. ;; Is the number a rational ( not a decimal ), true or false (integer? 1.3) ;; Is the number an integer, true or false (ratio? 22/7) ;; Is the number a decimal number expressed as a ratio, true or false (decimal? 1.4) ;; Is the number a decimal number not expressed as a ratio, true or false (float? 3) ;; Is the number a floating point number, true or false
So thats it, thats a real basic introduction to Clojure, next lesson will introduce you to functional programming. After all isn’t that why you are learning Clojure, its all about the functions !
Once we get your head into functional programming we look at core types of Lists, Vectors, Sets and Maps, and we use functional programming to manipulate them