Hello! Welcome to the third lesson in our series.
In the last session, we set up a standard Clojure project structure for our fx-calculator application, creating the src directory and the deps.edn configuration file. You now have a proper project, but it's just a collection of files.
Today, we will bring that project to life. The learning outcome for this lesson is to initiate a CIDER REPL and practice evaluating basic Clojure expressions directly from a source file. This is the foundational workflow for all Clojure development and is what makes the language so interactive and productive.
By the end of this lesson, you will be able to:
- Launch a CIDER REPL connected to your project.
- Evaluate Clojure code from your source file and see the results instantly.
- Understand and use the basic commands for this interactive workflow.
Let's get started.
1. Launching the CIDER REPL
So far, you have Emacs configured for Clojure and a project ready to go. The next step is to start a Clojure process and connect Emacs to it. CIDER makes this seamless with a process called "jacking in."
When you "jack in," CIDER does a few things automatically:
- It reads your project's
deps.ednfile. - It calculates the classpath (the set of source directories and dependencies).
- It starts a new Clojure process running an nREPL server.
- It connects your Emacs session to that server, giving you a REPL buffer.
The following video demonstrates this process.
Emacs: introduction to Clojure (CIDER and clojure-mode)
This segment from Protesilaos Stavrou's video 'Emacs: introduction to Clojure' shows how to launch the CIDER REPL from a Clojure file.
Watch the section from 01:46 to 04:00. Observe the use of the cider-jack-in-clj command and the explanation of what a REPL (Read-Eval-Print-Loop) is.
Exercise: Jack-in to Your Project
Now, it's your turn.
- Open your
fx-calculatorproject in Emacs. If you use a project manager likeprojectile, open the project. Otherwise, just open thesrc/fx_calculator/core.cljfile. - With the
core.cljfile open, pressC-c M-j(orM-x cider-jack-in-clj). - You will see some output in the minibuffer and then a new window will appear with the CIDER REPL. It will show a prompt like
fx-calculator.core=>.
The prompt is important. It tells you that the REPL's current namespace is fx-calculator.core, which matches the namespace of the file you jacked-in from. This means any functions you define in this file will be available in the REPL once evaluated.
2. Evaluating Code from the Source File
While you can type code directly into the REPL, the most effective workflow is to write your code in your .clj source files and send it to the REPL for evaluation. This keeps your source files as the single source of truth. Your familiarity with Lisp will make the concept of evaluating "symbolic expressions" (S-expressions) feel natural.
CIDER provides several commands to evaluate code directly from a source buffer. The video below introduces the most common ones.
Emacs: introduction to Clojure (CIDER and clojure-mode)
This next clip from the same video demonstrates the core of the REPL-driven workflow: evaluating expressions from a source file directly into the running REPL.
Watch from 04:45 to 08:15. Pay close attention to the three evaluation commands shown: cider-eval-last-sexp (C-x C-e) cider-eval-defun-at-point (C-M-x) C-c C-c (which is often bound to cider-eval-defun-at-point)
As the video explains, these commands let you send code to the REPL without ever leaving your source file.
C-x C-e(cider-eval-last-sexp) is useful for evaluating small, inner expressions. You place your cursor after the closing parenthesis.C-M-x(cider-eval-defun-at-point) is for evaluating the entire top-level expression (like a function definition) that your cursor is inside. This is one of the most frequently used commands.
3. The Interactive Development Loop
Now let's put this together into a complete workflow: write, evaluate, test.
Your core.clj file should contain the -main function from the previous lesson:
(ns fx-calculator.core)
(defn -main []
(println "Hello, FX Calculator!"))
Let's evaluate this function and run it.
-
Evaluate: Place your cursor anywhere inside the
(defn -main ...)form incore.cljand pressC-M-x. You should see a confirmation in the minibuffer that the#'fx-calculator.core/-mainvar has been defined. -
Switch to REPL: Press
C-c C-z(cider-switch-to-repl-buffer) to jump to the REPL buffer. -
Test: At the REPL prompt, type the following and press Enter:
(-main)You should see
Hello, FX Calculator!printed to the REPL, followed bynil(the return value ofprintln).
This cycle is the essence of REPL-driven development. You write code in your editor, send it to the live process to update its state, and then interact with it in the REPL to verify its behavior.
Exercise: Define and Test a New Function
Let's reinforce this loop by adding a new function.
-
In
core.clj, add the following function definition below your-mainfunction:(defn square "Computes the square of a number." [x] (* x x)) -
With your cursor inside the
(defn square ...)form, evaluate it usingC-M-x. -
Switch to the REPL with
C-c C-z. -
Test your new function with a few different inputs:
(square 5) ;;=> 25 (square 1.5) ;;=> 2.25
You've just experienced the core feedback loop of Clojure development. Notice how you didn't have to recompile your entire project or restart the application. You simply updated the running system with your new definition.
The following video segment provides a longer demonstration of this iterative process of defining functions, evaluating them, and testing them in the REPL.
Emacs: introduction to Clojure (CIDER and clojure-mode)
This final clip shows the development loop in action, including defining functions with arguments, evaluating them, and switching to the REPL to test them.
Watch from 08:15 to 12:09. This demonstrates the entire write-evaluate-test cycle. Notice how the developer uses C-M-x to evaluate the function definition and C-c C-z to quickly switch to the REPL to call it.
4. Essential Commands Summary
Here is a summary of the key commands you've learned in this lesson. These will become muscle memory very quickly.
| Command | Keybinding | Description |
|---|---|---|
cider-jack-in-clj |
C-c M-j |
Starts a REPL process and connects CIDER to it. |
cider-eval-defun-at-point |
C-M-x |
Evaluates the top-level form at the cursor's position. |
cider-eval-last-sexp |
C-x C-e |
Evaluates the S-expression immediately before the cursor. |
cider-switch-to-repl-buffer |
C-c C-z |
Switches focus between your source file and the REPL buffer. |
Conclusion
In this lesson, you connected your development environment to your project and experienced the interactive, REPL-driven workflow that is a hallmark of Clojure. You learned how to start a CIDER session and, most importantly, how to evaluate code from your source files directly into the running application.
Key Takeaways:
- Jacking-in (
C-c M-j) is the standard way to start a CIDER REPL session for a project. - The primary workflow is to write code in
.cljfiles and send it to the REPL for evaluation. C-M-xis your go-to command for evaluating function definitions and other top-level forms.- The write-evaluate-test loop provides an immediate feedback cycle, allowing for rapid and incremental development.
You now have the fundamental skills for writing and running Clojure code. In our next lesson, we will deepen your REPL skills by exploring how to utilize the REPL for common development tasks like loading and reloading namespaces, inspecting data, and looking up documentation, all without leaving Emacs.