Tutorial 09
Tutorial 09
TUTORIAL 9
Clojure: Setup and Introduction
Check if java is already installed, any version >= 8 is fine, default recommended version is 11.
a. Run `java --version` and `javac --version` in ubuntu terminal. If the commands do not show any output,
proceed with the following steps.
b. Run `sudo apt update` in terminal to update the package lists.
c. Run `sudo apt install default-jre` to install the default java runtime.
d. Run `sudo apt install default-jdk` to install the default java development environment.
e. Run `java --version` and `javac --version` again to ensure java is installed, it should produce the following
output.
2
Setting up a development environment for Clojure
2. Installing Leiningen
Leiningen is a tool for building clojure projects.
a. Run `sudo apt update` in ubuntu terminal to update the package lists.
b. Run `sudo apt install leiningen` to install leiningen package.
c. Run `lein new app hello-world` to create a hello-world project to test the installation. It should should display the following output.
d. Enter the newly created hello-world directory with `cd hello-world` and run `lein run`. For the first run of the project, clojure
dependencies will be downloaded. Ensure that the following output is displayed and the last line of the output displays
“Hello, World!”
f. To ensure that the project source code has been loaded up into the clojure REPL, try running the main function as defined in
hello-world/src/hello_world/core.clj by typing `(-main)` in the REPL.
4
Setting up a development environment for Clojure
Optionally, an extension can be installed for Visual Studio Code. It provides features such as auto-
completion in clojure REPL, importing source code quickly into the REPL etc.
1. If WSL is being used, ensure Visual Studio Code is connected to Ubuntu WSL (lower left icon
should display “WSL:Ubuntu”, follow steps outlined in tutorial 0 for WSL-VS Code plugin)
2. Open Extensions and search for “Calva” and install the extension. For WSL, ensure that “Install in
WSL: Ubuntu” is selected from the drop down menu.
6
COMP 348 Principles of Programming Languages
Hello World!
● In REPL, we start by defining the following function:
(fn [] "Hello World!")
● On evaluation, this produces the following output:
#function[...]
7
Function as a unit of computation
8
First class functions
● Clojure has first class functions i.e. functions can be saved in labels, they can
be passed to other functions as arguments, and functions can return functions
as well.
● To store a lambda function in a label:
(def hello (fn [] "Hello World!"))
● To invoke it:
(hello) -> "Hello World!"
● In fact, a function passed as an argument to another function which has
access to the context of the receiving function’s state is called a closure, a
keypoint after which the language is named.
COMP 348 Principles of Programming Languages
9
Variables and atoms
● ‘def’ is used to bind a value to a variable label: (def a 5)
● The identifier follows similar rules to other programming languages, it can contain alphabets, numbers and
underscore, and it cannot begin with a number. The identifier is case sensitive.
● Note that bound variables are immutable, to be reassigned they have to be destroyed and recreated again.
● For modifiable state, clojure uses ‘atoms’, these atoms can be thought of as references to variables that
can be updated in a thread-safe manner.
(defn Atoms Output:
; Conditionally update the value if the
[]
expected value is found
(def amount (atom 100)) Amount: 100
(compare-and-set! amount 110 120) ; will
(println "Amount: " @amount) Incremented amount: 101
update the value, as amount was 110
Amount after resetting: 110
(println "Comparing with 110 and updating
; Exactly one thread can perform any of the Comparing with 110 and updating to 120,
to 120, amount: " @amount)
following updates amount: 120
; Apply a function on the atom to update its Comparing to 110 and updating to 150,
(compare-and-set! amount 110 150) ; will
value amount: 120
not update the value, as amount was 120
(swap! amount inc) nil
(println "Comparing to 110 and updating
(println "Incremented amount: " @amount)
to 150, amount: " @amount))
11
Operators
● Clojure provides 4 standard types of operators: arithmetic, relational, logical
and bitwise.
; arithmetic ; relational ; logical operators ; bitwise operators
(+ 1 2) (= 2 2) ; true (and true false) ; false (bit-and 5 12) ; 0101 1100 -> 0100
(- 5 3) (not= 2 3) ; true (or true false) ; true (4)
(* 6 3) (< 2 3) ; true (not true) ; false (bit-or 5 12) ; 0101 1100 -> 1101
(/ 3 2) (<= 3 3) ; true (13)
(inc 5) (> 3 6) ; false (bit-xor 5 12) ; 0101 1100 -> 1001
(dec 5) (>= 2 3) ; false (9)
(max 3 6) (bit-not 5) ; 0101 -> 1010
(min 3 6)
(rem 5 3)
● Note that operator precedence isn’t inferred here, we explicitly specify the
order by creating lists that will be evaluated.
COMP 348 Principles of Programming Languages 12
Conditionals in clojure: if and if-do
● Basic construct: (defn conditionalIf (defn conditionalIfDo
[] []
(if boolean-form
(println "conditionalIf:") (println "\nconditionalIfDo:")
then-form
(if (and (= 5 5) (or (= 2 2) (if (= 5 6)
optional-else-form
(not true))) (do (println "Equal: first statement")
)
(println "True") (println "Equal: Second statement"))
● For eg:
(println "False"))) (do (println "Not equal: first statement")
● Output: ● Output:
conditionalCase: conditionalCond:
I have a dog amount <= 100
14
Introduction to functions
● A function in clojure follows the following format. The return value of the function is the value of the last expression.
(defn sum
"Compute sum of numbers recursively"
Output:
[n]
(if (<= n 1) (sum 10) -> 55
n
(+ n (sum (- n 1)))))
COMP 348 Principles of Programming Languages
15
Introduction to functions
● Fibonacci numbers computed recursively. ● Factorial computed recursively.
16
References
1. https://clojure.org/guides/install_clojure
2. https://leiningen.org/#install
3. https://muyiwa.medium.com/getting-started-with-clojure-and-visual-studio-
code-15ef6283c496
4. https://calva.io/
5. https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md
6. https://clojure.org/guides/learn/syntax
17