Clojure is a dialect of the Lisp programming language that has long been known by the free software community, but Clojure runs on the Java Virtual Machine JVM, and has conquered corporate environments precisely by maintaining compatibility with JAVA and being a pure language functional.

I’ve already studied and worked with various programming languages, but what struck me the most in Clojure is its almost alien syntax, I remembered the movie the Predator, great.


1. Installing

I used FreeBSD to make this article, so to install Clojure on FreeBSD simply type in the terminal the commands:

pkg install clojure leiningen 

In the above command we installed Clojure and Leiningen to automate projects.

1.1 Start

Open another terminal session and enter the command lein repl:

lein repl

nREPL server started on port 23024 on host - nrepl://
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_172-b11
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e


Ok, now it’s possible for you to type the code in clojure and see the results.

user=> (println "Hello World")
Hello World

All interaction with clojure starts with parentheses (…), as we can see we did a classic Hello World using the function println and it returns nil equivalent to a void or null.

1.2 Creating Functions

To create functions we use defn:

user=> (defn sigma [x y]
  #_=> (+ x y))

If you wanted to multiply for example, just use the * operator or to divide /.

You can use the TAB to fill in commands automatically. Another example, looking for the intersection of the two vectors:

user=> (clojure.set/intersection #{:a :b :c} #{:b :a :d})
#{:b :a}

1.3 Using reduce, map, filter

Reduce syntax:

user=> (reduce + 0 '(1 2 3 4 5 6 7 8 9 10))

user=> (reduce * 1 '(1 2 3 4 5 6 7 8 9 10))

Map syntax:

user=> (map inc [1 2 3])
(2 3 4)

user=> (map str ["a" "b" "c"] ["A" "B" "C"])
("aA" "bB" "cC")

Filter syntax:

user=> (def human-version
  #_=> [{:v 1.0 :day 100} 
  #_=>  {:v 2.0 :day 5}
  #_=>  {:v 1.5 :day 10}])

user=> (filter #(< (:v %) 2) human-version)
({:v 1.0, :day 100} {:v 1.5, :day 10})

1.4 More advanced Lazy Seqs

Let’s create a fictional alien database:

(def alien-database
  {0 {:makes-blood-puns? false, :has-pulse? true  :name "Predator"}
   1 {:makes-blood-puns? false, :has-pulse? true  :name "Alien"}
   2 {:makes-blood-puns? true,  :has-pulse? false :name "E.T"}
   3 {:makes-blood-puns? true,  :has-pulse? true  :name "Yoda"}})

(defn alien-related-details
  (Thread/sleep 1000)
  (get alien-database social-security-number))

(defn alien?
  (and (:makes-blood-puns? record)
       (not (:has-pulse? record))

(defn identify-alien
  (first (filter alien?
                 (map alien-related-details social-security-numbers))))

Let’s see how long it takes to execute the function below:

user=> (time (alien-related-details 0))
"Elapsed time: 1021.035913 msecs"
{:makes-blood-puns? false, :has-pulse? true, :name "Predator"}

Creating a range:

user=> (time (def mapped-details (map alien-related-details (range 0 1000000))))
"Elapsed time: 0.182146 msecs"


Clojure is a very cool language to work on, at least it was my first impression, predicting to do other more advanced language tutorials, possibly using clojure for data analysis.