What is Clojure?
Clojure is a modern programming language. Depending on your skill level, you can create any type of software with Clojure. This includes games, web apps, mobile apps, and desktop applications.
The first step in programming Clojure is to install it and other things needed for creating Clojure programs.
Continue reading “Hello Clojure”
Most of the Clojure tutorials and Clojure examples on this site require at the minimum Clojure to be installed. Usually, you want Leiningen installed too.
Seriously, do it once and ignore it for the rest of your learning experience. Here are the steps for getting Lein and Clojure up and running.
Continue reading “Installing Clojure with Lein”
If you’re interested in making a commercial grade Clojure web app that deploys as a Docker container, this is the tutorial for you.
Prerequisites: You will need Leiningen and Docker installed.
First step needed is to create a Clojure web app template project. I used the following command.
lein new luminus mywebapp +reitit +http-kit +mysql +swagger +auth
This creates a Clojure web app using the Luminus Framework, Reitit for mapping of incoming requests to the proper handlers, HTTP Kit for HTTP handling, MySQL for JDBC connections to our MySQL database, Swagger for API support, and Buddy for authentication middleware. Your new web app is in the directory,
Continue reading “Clojure Docker Web Apps”
Sometimes you need to configure
lein to use a custom JDK. On Linux, set the environment variable
JAVA_CMD to point to the
java executable you want
lein to use.
For example, you might add the following lines to your
#used by LEIN
Once you update your bash profile, you can start using your configuration by using the following command.
In Clojure, if you want a basic OOP behavior without killing yourself to fully implement Java classes and interfaces in Clojure, the preferred technique is to use records. Sometimes implementing protocols in records suits your needs, mostly due to speed of code execution. However, if you want polymorphism with your records, then multimethods are where it’s at.
Admittedly, multimethods are very flexible, so the technique I’ll show you is one of many techniques you could use. The basic pattern I use for inheritance with records, is to use the
derive command with keywords that are kept as a value in the record. For example,
(defrecord food [
(defn construct-food [name color yummy]
(->food ::food name color yummy))
(derive ::fruit ::food)
(defrecord fruit [
(defn construct-fruit [name color yummy needs-peeling]
(->fruit ::fruit name color yummy needs-peeling))
type is used to track
isa relationships of
derive is used to set
::food as the parent of
::fruit . Notice the use of custom constructors to set default values for
type in the records.
Continue reading “Clojure Record Heirarchy”
Most of the time, Clojure does not need locks like Java and other languages. This is because of
ref s, and
agent s. I’ll focus on Clojure agents in this short post.
Agents are handled in single-threaded queues. By lining up calls of a function in a queue, no locks are needed. When combined with
send-off , deadlocks won’t happen.
Here’s a quick example.
(def x (agent 0))
(println "Starting send-offs for agent")
(dotimes [_ 10]
(send-off x mod-x)
(println "x is now" @x))
(println "final value ... " @x)
A few things are going on here, so let’s look at them.
Continue reading “Clojure Agents”
Want some Object Oriented Programming in Clojure? Here’s a quick example.
Let’s create a dog object.
"Just a protocol"
(barking [this] "bark")
(hungry [this] "hangry")
(defrecord Dog [breed ^Integer age color]
(barking [this] (str "barking my breed ... " (:breed this)))
(hungry [this] (str "I'm so hungry I could age one whole year to ... " (str (inc (:age this)))))
(sleeping [this] (str "Really tired, and it has nothing to do with my fur color that is " (:color this)))
Now let’s use the dog object.
[temp2020toss.dogo :refer :all])
(:import (temp2020toss.dogo Dog)))
"I don't do a whole lot ... yet."
(println "Hello, World!")
(let [my-dog (Dog. "chow" 8 "green")]
(println "-->" (:breed my-dog))
(println "-->" (barking my-dog))))
See, OOP in Clojure is fairly simple. This sample uses protocols with records, but you can add polymorphism with just a little extra work. For polymorphism, use records and multimethods.
I absolutely love the user razvan’s Clojure
defrecord example over at stackoverflow, so I copied it here. I know I’ll never find it again if I don’t. Look at the original over on stackoverflow at this link.
Here’s the example …
Clojure defrecord example:
;;define Address record
(defrecord Address [city state])
;;define Person record
(defrecord Person [firstname lastname ^Address address])
;;buid the constructor
(defn make-person ([fname lname city state]
(->Person fname lname (->Address city state))))
;;create a person
(def person1 (make-person "John" "Doe" "LA" "CA"))
(:city (:address person1))
If you’re looking for more information on combining protocols with records in Clojure, then Matthew Boston has the blog for you!
NOTE: All the code in this tutorial can be quickly tested at the REPL using the command
lein repl to start a REPL to test with.
One of the first things you learn when learning clojure is
println . For example,
That’s probably the first Clojure program you ever wrote. Maybe you wrote this variation.
print are the first ways learned of displaying output in Clojure, most Clojure developers continue using them when debugging code. Nothing wrong with that. But sometimes it is better to use a more specialized tool.
In steps the
pr commands. These two commands are tailored for printing objects. At first glance, they appear to work the same as
println . However, they actually show more information in some instances.
println , the
\n in the following code quietly gets replaced by the action of a new line being printed.
prn are used, the two characters
n are displayed instead of an actual new line. This is very handy when hidden characters are fowling up your layout, or needed to be visible when debugging code.
Final note: The only difference between
prn , is that
prn prints a new line after the objects it is printing out.
When coming from other languages, devs often think the best way to check for an empty vector or other sequence in Clojure is to either check the
count is less than one or check for
(not (empty? some-seq)) . Both will work, but are not idiomatic, meaning “Your newbness is showing.” Continue reading “Checking for Empty Seqs in Clojure”