Head into Clojure – Part 1: The Basics

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