What is Clojure? Functional Programming for the Java Ecosystem
Most programming languages are built on procedural programming, but there is this niche of dialects built for “functional programming,” where code classes are dynamically created based on the rules in the functions you write. If you could put languages on a scale of most procedural to most functional, you’d find Clojure sitting at the edge of the latter. What is Clojure? Who uses Clojure? What’s the best Clojure use case? And what does Rookout has anything to do with Clojure debugging?
Why Choose Clojure?
If you want to get all the benefits of using a JVM and also rely on a modern functional programming language, while also getting an extremely enthusiastic support community, well then Clojure is the language for you. You can also look at this mindmap that one community member shared on Reddit several months ago:
Firstly, a quick rundown of functional programming languages. No language is purely functional or purely not. Functional is just one of several programming paradigms alongside object-oriented programming, procedural, imperative, declarative, and others.
Clojure is as close to purely functional as languages get. Mainly functional Lisp can work across paradigms, while primarily imperative C# is also general-purpose and applies across the board.
Clojure’s Enthusiastic Community
There aren’t many languages in popular use that have limited paradigm range. But Clojure does enjoy a sizeable user community. A decent 2.25% of the professional developers that responded to Stack Overflow’s 2021 Developer Survey had used Clojure (which is actually up from 2019, but more people answered the question that year).
But that’s nothing to its actual popularity. A whopping 81.2% said they “loved” the language – that is up from 68.3% in 2019! It ranks 2nd place behind Rust. That raises an obvious question – WHY? Notwithstanding that some devs actually compare the Clojure community to a cult (no seriously, a lot of Clojure enthusiasts also wonder this), what is the main appeal of Clojure?
The Clojure community is small but tight. You can get support from that community at portals Ask Clojure, ClojureVerse and the Google Group. There are also Clojure-specific IDEs: Calva (for Visual Studio Code), Cursive, and CIDER with adding interactive programming support to Clojure development. Popular Projects include HTTP routing library Compojure; REST API framework Liberator, and HTTP API framework Pedestal.
Adapting Functional Programming to Java
A big theme is efficiency: It utilizes the JVM ecosystem without depending on Java; it’s a dialect of a wider-known language Lisp.
So let’s swim a little bit deeper. Clojure does have some relatability to Java, a procedural language. That procedure is the compilation of code, also called a class. Java has got a lot of class. Clojure…erm, is pretty classless – at least at first. So when you run Java, the file opens; when you run Clojure, it relies on the functions in the code to generate a class file.
Now, this can be both awesome and awful, depending on your perspective. Functional programming in Java carries a huge learning curve with it for a lot of developers. Lisp syntax is particularly extreme when it comes to focus on functions.
“Hello, World!” in Clojure
Clojure syntax uses “S-expressions,” or lists grouped together inside of parentheses. It is scant on notation outside of the operator at the beginning of each expression. There are no infixes or suffixes.
You can see that here in the Clojure version of
<span style="font-weight: 400;">Hello World!</span>:
(ns helloworld.core) (defn -main "Program description"  (println "Hello, World!"))
You can find a number of other common coding examples, including the seemingly endless amount of ways to program Fizzbuzz.
Debugging in the different IDEs and the language itself works through the REPL, or the Read-Eval-Print Loop used by the Lisp language. Within the Lisp REPL, you can “inspect and alter the flow of a running program” according to Clojure documentation.
The simplest method is to use Clojure’s print command
<span style="font-weight: 400;">println</span> to output all of your code as it executes. That might not exactly be practical. More sophisticated approaches within REPL include using the SpyScope library, which includes three reader tools:
spy/p– the “p” stands for “print”; it’s a less verbose approach to the
<span style="font-weight: 400;">println</span>debug method
spy/d– the “d” stands for “details”; adds time data, stack frames and other data
spy/t– the “t” stands for “trace”
You can also approach it from with the Java Debugger within a compatible IDE or open-source trace-based library Debux (specially written for Clojure and ClojureScript). That being said, there can be a special curve to debugging Clojure’s functional programming style.
Knowing this, Rookout provides its own debugging services for Clojure. Adding Rookout breakpoints will likely streamline what can otherwise be a flustering manual debugging process in an already confusing language. You can see a brief demonstration of how it works in the GIF below:
On top of Clojure, Rookout also supports any of the JVM-supported languages like Kotlin, Scala, Groovy, and ColdFusion.