Skip to the content.

Clojure

CLOJURE

Information

Installation

nano install-clojure.sh && chmod a+x install-clojure.sh
#!/bin/sh

curl -L -O https://github.com/clojure/brew-install/releases/latest/download/posix-install.sh
chmod +x posix-install.sh
sudo ./posix-install.sh --prefix /opt/clojure
sudo dnf install rlwrap

exit 0
nano hello.clj
(println "Hello, World!")
nano hello.sh && chmod a+x hello.sh
#!/bin/sh

clojure -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.11.1"}}}' -M hello.clj

exit 0

Configuration

Usage, tips and tricks

Prepare project

Clojure Spring Boot Execution

mvn spring-boot:run -Dspring-boot.run.arguments="-n info.setmy.main -s info/setmy/main.clj -m default-main"
java -jar .\target\clojure-0.0.0-SNAPSHOT.jar -n info.setmy.main -s info/setmy/main.clj -m default-main

Clojure maven plugin run

mvn clojure:run

Programming

; integer
42

; floating point (double)
-1.5

; ratio
22/7

; string
"hello"

; character
\e

; regular expression
#"[0-9]+"

; symbol
map

; symbol - most punctuation allowed
+

; namespaced symbol
clojure.core/+

; clojure.lang.Symbol
(type 'xyz)

; clojure.lang.Keyword
(type ':xyz)

; null value
nil

; booleans
true

false

; keyword
:alpha

; keyword with namespace
:release/alpha

; clojure.lang.Keyword
(type :a)

; clojure.lang.BigInt
(type 123N)
(type (bigint 123))

; java.math.BigInteger
(type (biginteger 123))

; vector
[1 2 3]

; list. At the case execute function 1 with params 2 and 3
(1 2 3)

; hash-map
{}

; set
#{}

Collections

Lists

Linked list.

Clojure functions calls are lists.

;; To initiate list with values use ' character. Othervise it is executed (read an interpreted) as function 1 with args 2 and 3.
;; ' is macro
;; clojure.lang.PersistentList
(type (quote (1 2 3)))
(type '(1 2 3))
(type (list 1 2 3))

(println (str '(1 2 3)))

Link: Lists

Vectors

Sequential, 0-base indexed.

;; clojure.lang.PersistentVector
(type [1 2 3])

(println (str [1 2 3]))

Link: Vectors

Sets

Unordered collection with unique vales in it.

;; clojure.lang.PersistentHashSet
(type #{:a :b :c})
(type (hash-set 1 2 3 4))

(println (str #{:a :b :c}))
(println (str (hash-set 1 2 3 4)))
(println (str {"firstName" "Imre" "lastName" "Tabur"}))

;; #{2.0 1 true "abc" 3 2}
(hash-set 1 2 3 "abc" true 2.0 "abc")

;; Syntax error reading source at (REPL:1:30).
;; Duplicate key: abc
#{1 2 3 "abc" true 2.0 "abc"}

Link: Set

Maps

;; clojure.lang.PersistentArrayMap
(type {:a 1 :b 2})

(println (str {:a 1 :b 2}))

Link: Maps

Namespaces

;; clojure.lang.PersistentArrayMap
{:person/first "Han"
 :person/last  "Solo"
 :person/ship  {:ship/name  "Millennium Falcon"
                :ship/model "YT-1300f light freighter"}}

Link: Maps

Symbols

;; clojure.lang.Symbol
(type 'abcDEF)

(def plusFuncSymbol '+)

(eval (list plusFuncSymbol 1 2 3))

(def listFunc (list plusFuncSymbol 1 2 3))

(eval listFunc)

Equality

;; true
(= 2 (+ 1 1))

;; false
(= 2 2.0)

;; true
(== 2 2.0)

;; java.lang.Boolean
(type (= 2 (+ 1 1)))

Functions

(defn greet [name] (str "Hello, " name))

;;  This is equivalent as with anonymous function
(def greet (fn [name] (str "Hello, " name)))

(defn messenger
    ([] (messenger "Hello world!"))
    ([msg] (println msg)))

(defn hello [greeting & who]
    (println greeting who))

(greet "Ernie")

(messenger)
(messenger "Hello class!")

(hello "Hello" "world" "class")

Anonymous Functions

;; Just example syntax
(fn [message] (println message))

((fn [message] (println message)) "Hello world!")

;; Equivalent to: (fn [x] (+ 6 x))
#(+ 6 %)

;; Calling that
(#(+ 6 %) 1)

Let

; 1
(let [x 1]
    x)

; 3
(let [a 1
      b 2]
    (+ a b))

; 8
(let [c     (+ 1 2)
      [d e] [5 6]]
    (-> (+ d e) (- c)))

; "1 2 3 4"
(let [aList     (list 1 2 3 4)
      [a b c d] aList]
    (str a " " b " " c " " d))

misc

(-> "Look "
    (str "I'm ")
    (str "writing ")
    (str "clojure."))

(def makeList
    (->> (range 1 10)
         (map println)))

(def makeList
    (->> (range)
         (map inc)
         (take 5)))

; Exactly this way
makeList

(->> (range 1 10)
     (map (fn [x] (println x) x))
     (take 4))

; "2022-11-13T19:29:40.944111600Z"
(str (java.time.Instant/now))

; "2022-11-13T21:30:41.775844700"
(str (java.time.LocalDateTime/now))

(str (bean (java.time.LocalDateTime/now)))

; #inst "2022-11-13T19:29:52.015-00:00"
(java.util.Date.)

; Func passing and executing
(defn greet [value infunc] (str "Hello," (infunc value)))

(greet 2 (fn [x] (+ x 1)))

; 13.7
(get ["a" 13.7 :foo] 1)

; Filter, map, reduce
(def aVector [1 2 3 4 5 6 7 8 9])

(take 2 (map (fn [x] (* x 2)) (filter (fn [x] (= (rem x 2) 0)) aVector)))
(take 2 (map (fn [x] (* x 2)) (filter (fn [x] (= (rem x 2) 0)) aVector)))

(take-last 2 (map (fn [x] (* x 2)) (filter (fn [x] (= (rem x 2) 0)) aVector)))

; filter in even numbers from vector,map by multiplying by 2 and collect last 2 and collect into vector and sum the vector
(reduce +
        (into []
              (take-last 2 (map (fn [x] (* x 2)) (filter (fn [x] (= (rem x 2) 0)) aVector)))))

; Filtering hash map items list
(def person1 {:firstName "Joe" :lastName "Biden"})
(def person2 {:firstName "Donald" :lastName "Trump"})
(def person3 {:firstName "Barack" :lastName "Obama"})
(def personList (list person1 person2 person3))

(filter #(not= (:firstName %) "Joe") personList)

(remove #(= (:firstName %) "Joe") personList)

(filter #(not= "Joe" (get % :firstName)) personList)
(filter (fn [person] (not= (person :firstName) "Joe")) personList)
(filter (fn [person] (not= (get person :firstName) "Joe")) personList)
(filter #(not= (% :firstName) "Joe") personList)

(def strings ["1" "2" "3"])

; Mapping vector through mapping lambda to clojure.lang.LazySeq.
(println (map #(Integer. %) strings))

(def aVariable (conj #{} "Hello"))

; #{"World" "Hello"}
(conj aVariable "World")

; Better printout format
(println "Some object:" (pr-str some-object))

(ns my.lib.core
    (:import [org.apache.logging.log4j LogManager]))

(def log (LogManager/getLogger (str (ns-name *ns*))))

(defn foor []
    (.info log "Info message"))

Link: Functions

The thread-first macro (->)

Linear flow of calls for readability.

-> thing

Function composition

Make it work:

(defn double [x] (* 2 x))
(defn add-one [x] (+ 1 x))
(defn double-and-add-one (comp add-one double))

(double-and-add-one 3)

See also

IDE

Web Noir

Pedestal

Clojure diary

reduce spec

Liberator

Compojure

Ring

scicloj.ml

Cortex

Gorilla REPL

Clojure Style Guide

uncomplicate - CL libs for ML/AI

clj-commons

Codox

Korma

Clojure docs

Clojure the Devil

Clojure isn’t for me