ClojureClojure is a dialect of the Lisp programming language. Accordingly to Rich Hickey, creator of the language, “it is designed to be a general-purpose language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multithreaded programming.”
Ok, enough! Probably you can read definition and most of the “getting started” information somewhere else. I’m here to share my thoughts on this language and to inspire you to try it out.
Back in university days some of my peers had chance to learn Lisp. (My academic group instead had something else, maybe JavaScript, which I anyway haven’t learnt there.) So I only knew that there is such language as Lisp and it has something to do with lists. Now I know a little bit more – it is about LISt Processing… and I’ve also tried one of its dialects.
Clojure has its differences and some oddness, like, for example, prefix notations. Well, writing (* 5 (+ 2 3) ) instead of (5 * (2 + 3) ) is not difficult, but it is like saying “understand me later you will” in Yoda style! Also having few thousands of “((((“ and “)))))” makes code looking ugly as per me. Or maybe I’m too newbie in formatting source code. Honestly, except of idea that everything is list I didn’t grasp any concept which would sound completely new to me.

Some code

As you may know I’m reading “7 languages in 7 weeks” and for each language there is set of tasks. Initially I thought that I will take the most difficult task from Day 3 and implement it, but when I started coding I realized that it was too hard to be my first program in Clojure. So I took baby steps:
Day 1: Function big that returns true if st is longer than n.
(defn big [st n]
  (if ( > (count st) n) true false))

; usage
(big "is length of this string longer than 15?" 15)

Day 1: Function that identifies collection.

(defn collection-type [col]
       (cond
        (vector? col) (str "vector:")
        (list? col) (str "list:")
        (map? col) (str "map:")))

(collection-type [1])
(collection-type (list 1 2))
(collection-type {:chewie :wookie :lea :human})

Day 2: An unless with an else condition using macros.

(defmacro unless [test body]
    (list 'if (list 'not test) body))
    
(macroexpand '(unless condition body))

(unless (> 1 10) (println "Did you really think that 1 > 10?"))

Day 2: Type using defrecord that implements a protocol.

(defprotocol Person
    (writeName )
    (writeAge ))
    
(defrecord PersonImpl [name age]
    Person
    (writeName [_] (println name))
    (writeAge [_] (println age))
    Object
    (toString [this] (str "Name=" (writeName this) "& Age=" (writeAge this) )))
    
(def andriy (PersonImpl. "Andriy" 25))

(writeName andriy)
(writeAge andriy)
(println andriy)

Hey! Stop scrolling! :)
Day 3: Sleeping barber problem.

So, this is task which I thought I will do immediately after reading about Clojure, but I failed. I was able to perform it after I finished with those above. Here is what I had to solve (as in book):

Problem called “sleeping barber.” was created by Edsger Dijkstra in 1965. It has these characteristics:

  • A barber shop takes customers.
  • Customers arrive at random intervals, from 10 to 30 milliseconds.
  • The barber shop has three chairs in the waiting room.
  • The barber shop has one barber and one barber chair.
  • When the barber’s chair is empty, a customer sits in the chair, wakes up the barber, and gets a haircut.
  • If the chairs are occupied, all new customers will turn away.
  • Haircuts take 20 milliseconds.
  • After a customer receives a haircut, he gets up and leaves.

Write a multithreaded program to determine how many haircuts a barber can give in 10 seconds.

My solution:

(def counter (agent 0))
(def chairs (agent 0))
(def workingTime (agent 1))

(defn haircut [x]
    (do
        (Thread/sleep 20)
        (println "...haircutting...")
        (+ 1 x)))

(defn customer [x]
    (if (< x 3) 
        (do
            (send counter haircut)
            (println "I'm next!")
            (+ 1 x))
        (do
            (println "I went home. This barber shop sucks!")
            (- 1 x))))

(defn waitUntilEndOfTheDay [x]
    (do
        (Thread/sleep ( * 10 1000) )
        (println "[ Clock ticked end of working day ]")
        (dec x)
        ))
    
(send workingTime waitUntilEndOfTheDay)

(while 
    (pos? @workingTime)
        (do 
            (Thread/sleep ( + 10 (rand-int 21) ))
            (send chairs customer)))
            
(println "Barber has finished the day giving " @counter " haircuts.")
I have found many other solutions to this problem, like this one or another by Ben Nadel, or this or even more, but I like mine because it is original and one of the shortest solutions. Plus it has the most interactive output. Like in if you were in barber shop:


…haircutting…
I went home. This barber shop sucks!
…haircutting…
I’m next!
…haircutting…
I’m next!
I’m next!
[ Clock ticked end of working day ]
…haircutting…
Barber has finished the day giving  365  haircuts.
nil

It took me slightly more than one hour of real fun to solve this, but it worth every minute I spent. I like great feeling when something challenging was done. For sure it is one of the components of developer’s happiness.
Have I convinced you that there are a lot of interesting things in programming still awaiting you to pick them up?
Sorry for highlighting. I didn’t find appropriate Clojure highlighter.

If you haven't subsribed yet, you can subsribe below: