Variables in Clojure

Our first program will demonstrate how to declare and use variables in Clojure. Here’s the full source code:

(ns variables-example
  (:require [clojure.core :refer :all]))

(defn main []
  ; Define a variable using def
  (def a "initial")
  (println a)

  ; Define multiple variables at once using let
  (let [b 1
        c 2]
    (println b c))

  ; Clojure infers the type of initialized variables
  (def d true)
  (println d)

  ; Variables without initialization are nil in Clojure
  (def e nil)
  (println e)

  ; Use let for local bindings
  (let [f "apple"]
    (println f)))

(main)

In Clojure, variables are declared and used differently compared to some other languages:

  • The def special form is used to create global bindings (vars).
  • The let special form is used for local bindings.
  • Clojure is dynamically typed, so type declarations are not necessary.
  • Uninitialized variables are nil by default.

To run the program, save it as variables_example.clj and use the Clojure CLI or REPL:

$ clj -M variables_example.clj
initial
1 2
true
nil
apple

Clojure programs are typically run directly without a separate compilation step. However, you can compile Clojure code into Java bytecode for faster startup:

$ clj -e "(compile 'variables-example)"
variables_example__init.class
$ clj -M variables_example.clj
initial
1 2
true
nil
apple

Now that we’ve seen how to declare and use variables in Clojure, let’s explore more features of the language.