Browse Clojure Foundations for Java Developers

Evaluating Expressions in Clojure REPL: A Guide for Java Developers

Explore how to evaluate expressions in the Clojure REPL, including arithmetic operations, function definitions, and data structure manipulations, tailored for Java developers transitioning to Clojure.

4.2 Evaluating Expressions§

Welcome to the world of Clojure, where the REPL (Read-Eval-Print Loop) is your interactive playground. As experienced Java developers, you’re accustomed to compiling and running your code to see results. In Clojure, the REPL allows you to evaluate expressions on the fly, making it a powerful tool for experimentation and learning. In this section, we’ll explore how to evaluate various types of expressions in the REPL, including simple arithmetic, function definitions, and data structure manipulations.

Understanding the REPL§

Before diving into evaluating expressions, let’s briefly understand what the REPL is and why it’s essential in Clojure development. The REPL is an interactive environment where you can enter Clojure expressions, evaluate them, and see the results immediately. This immediate feedback loop is invaluable for testing ideas, debugging, and learning the language.

Simple Arithmetic in the REPL§

Let’s start with something familiar: arithmetic operations. In Clojure, arithmetic expressions are written in prefix notation, which might be different from what you’re used to in Java. Here’s a simple example:

;; Adding two numbers
(+ 3 5) ; => 8

;; Subtracting two numbers
(- 10 4) ; => 6

;; Multiplying two numbers
(* 6 7) ; => 42

;; Dividing two numbers
(/ 20 4) ; => 5

In Clojure, the operator comes first, followed by the operands. This prefix notation is consistent across all operations, making it easy to remember and use.

Try It Yourself§

Open your REPL and try evaluating these expressions. Experiment by changing the numbers and operators to see how the results change.

Function Definitions§

Functions are first-class citizens in Clojure, meaning you can define, pass, and return them just like any other data type. Let’s define a simple function in the REPL:

;; Defining a function to add two numbers
(defn add [a b]
  (+ a b))

;; Calling the function
(add 3 5) ; => 8

In this example, we define a function add that takes two parameters, a and b, and returns their sum. The defn keyword is used to define functions in Clojure.

Comparing with Java§

In Java, defining a similar function would look like this:

public int add(int a, int b) {
    return a + b;
}

Notice how Clojure’s syntax is more concise and expressive, focusing on the operation rather than the boilerplate code.

Try It Yourself§

Define your own functions in the REPL. Try creating a function that multiplies two numbers or calculates the factorial of a number.

Data Structure Manipulations§

Clojure provides a rich set of immutable data structures, including lists, vectors, maps, and sets. Let’s explore how to manipulate these data structures in the REPL.

Lists§

Lists are ordered collections of elements. Here’s how you can create and manipulate lists in Clojure:

;; Creating a list
(def my-list '(1 2 3 4 5))

;; Accessing the first element
(first my-list) ; => 1

;; Accessing the rest of the list
(rest my-list) ; => (2 3 4 5)

;; Adding an element to the front
(cons 0 my-list) ; => (0 1 2 3 4 5)

Vectors§

Vectors are similar to lists but provide efficient random access. Here’s how you can work with vectors:

;; Creating a vector
(def my-vector [1 2 3 4 5])

;; Accessing an element by index
(nth my-vector 2) ; => 3

;; Adding an element to the end
(conj my-vector 6) ; => [1 2 3 4 5 6]

Maps§

Maps are collections of key-value pairs. Here’s how you can create and manipulate maps:

;; Creating a map
(def my-map {:a 1 :b 2 :c 3})

;; Accessing a value by key
(get my-map :b) ; => 2

;; Adding a new key-value pair
(assoc my-map :d 4) ; => {:a 1, :b 2, :c 3, :d 4}

Sets§

Sets are collections of unique elements. Here’s how you can work with sets:

;; Creating a set
(def my-set #{1 2 3 4 5})

;; Checking if an element is in the set
(contains? my-set 3) ; => true

;; Adding an element to the set
(conj my-set 6) ; => #{1 2 3 4 5 6}

Try It Yourself§

Experiment with these data structures in the REPL. Try adding, removing, and accessing elements to see how they behave.

Comparing with Java Collections§

In Java, collections such as List, Map, and Set are mutable by default. Clojure’s immutable data structures provide several advantages, including thread safety and easier reasoning about code. Here’s a comparison of creating a list in Java and Clojure:

// Java List
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
;; Clojure List
(def my-list '(1 2 3 4 5))

Notice how Clojure’s syntax is more concise and expressive, focusing on the operation rather than the boilerplate code.

Exercises§

  1. Define a function in the REPL that calculates the square of a number.
  2. Create a vector of your favorite numbers and find the sum using the reduce function.
  3. Define a map with your name and age, then update the map to include your favorite color.

Key Takeaways§

  • The REPL is a powerful tool for evaluating expressions and experimenting with Clojure code.
  • Clojure uses prefix notation for arithmetic operations, which is consistent across all operations.
  • Functions are first-class citizens in Clojure, allowing for concise and expressive code.
  • Clojure provides a rich set of immutable data structures, offering advantages over Java’s mutable collections.

Further Reading§

For more information on Clojure’s data structures and functions, check out the Official Clojure Documentation and ClojureDocs.


Quiz: Mastering Clojure Expressions in the REPL§