Best Clojure Tutorial | Ultimate Guide to Learn [UPDATED]
Clojure Tutorial ACTE

Best Clojure Tutorial | Ultimate Guide to Learn [UPDATED]

Last updated on 20th Jan 2022, Blog, Tutorials

About author

Niyati Joshi (Java Software Engineer )

Niyati Joshi is a Java Software Engineer with 5+ years of experience as a Java Specialist. She is an expert in JavaScript, HTML/CSS, SQL, Python, Looker ML, DBT, PDT Looker, Looker API, Lightdash, Snowsight, and CARTO's SQL API.

(5.0) | 18632 Ratings 1503
    • Introduction
    • About the technology
    • What is a closure tutorial?
    • History
    • How do you explain closure?
    • Applications
    • Keywords and Symbols
    • Functional Programming Constructs
    • Scope
    • Working of Clojure
    • Features of Clojure Tutorial
    • Clojure offers a wide variety of built-in data types
    • Floating point
    • Retrospect
    • Basic Architecture
    • Advantages and Disadvantages
    • Prerequisites
    • Conclusion

    Subscribe For Free Demo


      Closure is a functional programming language that runs entirely on the Java Virtual Machine, in a similar way to Scala and Kotlin. Clojure is considered to be a Lisp derivative and will be familiar to anyone who has experience with other Lisp languages. This tutorial gives an introduction to the Clojure language, introducing how to get started with it and some of the key concepts to how it works.

      About the technology:

      Clojure is a high-level, dynamic functional programming language. Clojure is designed based on the LISP programming language and has compilers that make it run on both Java and .Net runtime environment.

      Before we talk about Clojure, let’s just have a quick description of the LISP programming language. LISPs have a tiny language core, almost no syntax, and a powerful macro facility. With these features, you can bend LISP to meet your design, instead of the other way around. LISP has been there for a long time dating back to 1958.

      Common LISP reads in an expression, evaluates it, and then prints out the result. For example, if you want to compute the value of a simple mathematical expression of 4+6 then you type in.

      What is a closure tutorial?

      The closure is when a function can access its lexical scope, even when that function is executing outside its lexical scope. Or, Inner functions can access their parent scope, even after the parent function is already executed

    Course Curriculum

    Learn Advanced Clojure Certification Training Course to Build Your Skills

    Weekday / Weekend BatchesSee Batch Details


      The History of Programming Languages conference series produces accurate historical records and descriptions of programming language design, development, and philosophy. It is infrequently held: the first three were in 1978, 1993, and 2007. 2020 is the time for HOPL-IV, and I’m very excited and honored to have a paper on Clojure be accepted. I want to thank Guy Steele and Richard Gabriel, co-chairs of HOPL IV, as well as the reviewers and shepherds for their support and guidance. Clojure is not the product of traditional research and (as may be evident) writing a paper for this setting was a different and challenging exercise. I hope the paper provides some insight into why Clojure is the way it is and the process and people behind its creation and development.

      How do you explain closure?

      A closure is a combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function.

       How do you explain closure ?
      How do you explain closure ?

      Clojure has the following high-level key objectives as a programming language:

    • It is based on the LISP programming language which makes its code statements smaller than traditional programming languages.
    • It is a functional programming language.
    • It focuses on immutability which is the concept that you should not make any changes to objects which are created in place.
    • It can manage the state of an application for the programmer.
    • It supports concurrency.
    • It embraces existing programming languages. For example, Clojure can make use of the entire Java ecosystem for the management of the running of the code via the JVM.


      Different applications are mentioned below:

    • Some of the applications in Clojure have enabled desktop creation and applications based on the web.
    • The desktop application in Clojure is created using a library called see-saw.
    • Config! An option can be used to change the value of the text on the desktop.
    • A modal dialog box can be displayed using the alert method of the see-saw class on the desktop.
    • Buttons class in Clojure enables to display of the buttons on the desktop.
    • Labels class in Clojure enables to display of the labels on the desktop.
    • Text class in Clojure enables to display of the text on the desktop.

      Keywords and Symbols:

      Clojure gives us the concept of both keywords and symbols. Keywords refer only to themselves and are often used for things such as map keys. Symbols, on the other hand, are names used to refer to other things. For example, variable definitions and function names are symbols. We can construct keywords by using a name prefixed with a colon:

          user=> :kw


          user=> :a


        Keywords have direct equality with themselves, and not with anything else:

          user=> (= :a :a)


          user=> (= :a :b)


          user=> (= :a “a”)


        Most other things in Clojure that are not simple values are considered to be symbols. These evaluate to whatever they refer to, whereas a keyword always evaluates to itself:

          user=> (def a 1)


          user=> :a


          user=> a


      Functional Programming Constructs:

      Clojure is, at its heart, a functional programming language. This means that we have access to many traditional functional programming concepts – such as map, filter, and reduce. These generally work the same as in other languages. The exact syntax may be slightly different, though.

      Specifically, these functions generally take the function to apply as the first argument, and the collection to apply it to as the second argument:

          user=> (map inc [1 2 3]) ; Increment every value in the vector

          (2 3 4)

          user=> (map inc #{1 2 3}) ; Increment every value in the set

          (2 4 3)

          user=> (filter odd? [1 2 3 4 5]) ; Only return odd values

          (1 3 5)

          user=> (remove odd? [1 2 3 4 5]) ; Only return non-odd values

          (2 4)

          user=> (reduce + [1 2 3 4 5]) ; Add all of the values together, returning the sum

    Course Curriculum

    Get JOB Oriented Clojure Training for Beginners By MNC Experts

    • Instructor-led Sessions
    • Real-life Case Studies
    • Assignments
    Explore Curriculum


    • When Clojure tries to resolve a symbol, the resolution will be done in the scope of the symbol.
    • Clojure tries to evaluate a because it needs to pass the value to print. a is bound to “aaa”, so “aaa” is printed in your terminal. Very straightforward.
    • Now, let are nested. Like the previous example, Clojure tries to resolve a. However, this time Clojure resolves a to “AAA”, instead of aaa. Each let will create a scope and symbol resolution is done inside the let where the symbol is resolved.
    • Also notice that the inner let does not override the scope of the outer let.
    • This kind of scope is called lexical scope. For those for whom English is not your first language, lexical means words in a sentence. The scope is lexical because the compiler relies on the physical location of the symbol (word) in a program (sentence) to resolve them.
    • The resolution looks up bubbles until it finds the binding. The inner let doesn’t provide the binding for a, so it bubbles up to the outer let. This happens because the scope of inner let is wrapped by the scope of outer let.
    • Clojure complains about being unable to resolve symbol exceptions when it cannot find the binding inside the given scope.
    • You probably find the idea of lexical scope very familiar. This is because most modern programming languages use lexical scope. There is also something called dynamic scope but you probably don’t have to know that right now.

      Working of Clojure:

    • It is a dynamic, functional, and high-level programming language whose design is based on a programming language called LISP, consisting of compilers that allow it to run on a run time environment of both Java and .Net.
    • LISP programming language does not have syntax, which is a tiny language providing a powerful macro feature.
    • The coding in it is smaller than other programming languages as it is based on the LISP programming language.
    • It consists of an immutable data structure not allowing changes to the objects created, and hence it’s a functional programming language.
    • The state of an application for the programmer is managed by conjure.
    • Concurrency is supported by conjure.
    • It can embrace existing programming languages.
    • Clojure as a programming language can be dealt with in two ways, namely Leininger and Eclipse plugin.
    • Clojure projects can be created, built, and automated using a tool called Leininger.
    • The development of Clojure can be done in Eclipse Integrated Development Environment using a plugin in Eclipse called Counter Clockwise.
    • The Clojure program files are saved with the.Cluj extension.

      Features of Clojure Tutorial:

      In contrast to most LISP languages, Clojure is a pragmatic programming language. It was designed to be used in the industry and indeed it is widely used especially in the domain of Web development. We will unveil many aspects of this design decision and describe at a high level what are the key features of Clojure that make it a pragmatic language that allows developers to solve real-life challenges. Most of those key features will be explored in detail later in the book. Don’t expect to understand deeply at this stage the features exposed in this lesson. You can think of it as a preview of Clojure’s key features.

    Features of Clojure
    Features of Clojure 

      Clojure offers a wide variety of built-in data types:

      Following is a list of data types which are defined in Clojure.

      1. Integers − Following are the representation of Integers available in Clojure.

      1. Decimal Integers − These are used to represent whole numbers. For example, 1234.

      1. Octal Numbers − These are used to represent numbers in octal representation. For example, 012.

      1. Hexadecimal Numbers − These are used to represent numbers in representation. For example, 0xff.

      1. Radix Numbers − These are used to represent numbers in radix representation. For example, 2r1111 where the radix is an integer between 2 and 36, inclusive.

      Floating point:

    • The default is used to represent 32-bit floating point numbers. For example, 12.34.
    • The other representation is the scientific notation. For example, 1.35e-12.
    • Char − This defines a single character literal. Characters are defined with the backlash symbol. For example, /e.
    • Boolean − This represents a Boolean value, which can either be true or false.
    • String − These are text literals which are represented in the form of chain of characters. For example, “Hello World”.
    • Nil − This is used to represent a NULL value in Clojure.
    • Atom − Atoms provide a way to manage shared, synchronous, independent state. They are a reference type like refs and vars.


      I’m not sure if this approach is a purist approach to clean architecture. Everything is very use case driven, and the architecture should make it clear what the intent of the application is. The concept of input and output ports is handled (cleanly in my opinion) by core. Sync channels. Dependency injection is handled (again cleanly in my opinion) by amount.

      I don’t have much experience building applications in Clojure(Script) – but I have leveraged similar concepts in larger apps using different languages. While a todo app can only teach so much – I was just floored by the elegance of Clojure(Script) in building a use case-centered app with different deliveries.

    Clojure Architecture
    Clojure Architecture

      Basic Architecture:

      The architecture lays out like so:

          resources/ — static assets leveraged by web delivery



          core/ — contains use cases, entities, and some simple conventions for messaging









          api/ — a simple restful api

          cli/ — a command-line interface to the app

          web/ — a re-frame application


          todo/ — protocol implementations for persisting todos

      Advantages and Disadvantages:

      Given below are the advantages and disadvantages:


    • It is a dynamic, functional, and high-level programming language whose design is based on a programming language called LISP, consisting of compilers that allow it to run on a run time environment of both Java and .Net.
    • LISP programming language does not have syntax, which is a tiny language providing a powerful macro feature.
    • The coding in it is smaller than other programming languages as it is based on the LISP programming language.
    • It consists of an immutable data structure not allowing changes to the objects created, and hence it’s a functional programming language.
    • The state of an application for the programmer is managed by conjure.
    • Concurrency is supported by conjure.
    • It can embrace existing programming languages.
    • As a programming language, it can be dealt with in two ways, namely Leiningen and Eclipse plugin.
    • It provides rapid prototyping as it is a dynamically typed language.


    • The primitive types in Clojure are all Java primitives, and performance penalties must be paid by Clojure run time while trying to wrap all the Java primitives.
    • Exception handling and exceptions are handled in Clojure by wrapping Java libraries, and in a production-ready environment, care must be taken to handle the exceptions well to avoid stack traces
    • The compiler throws a Java stack trace error in Clojure as Clojure is an interpreted language built above another run time. This makes it very difficult to rectify the problem as we cannot be sure if the cause of the error is a Java problem or conjure problem.
    • Clojure as a programming language has a complex set of rules, and hence the learning curve for conjure is the highest of any programming language.
    • The only editor supporting the Clojure development model is a working prototype of an editor based on REPL called Light Table. But Light Table has a small ecosystem of plugins that can be scaled to large projects only.
    • LISP programming experience is better only on a platform called Paredit. Code structuring is impossible in LISP unless the code is written on the Paredit platform; otherwise, it is difficult to make changes in the code.
    • It is not the ideal tool for short scripts and command-line utilities because the programs which need milliseconds to run consume one or two seconds of initialization time due to bootstrapping JVM and Clojure runtime cost.
    • Static typing and explicit typing are not supported in Clojure, making prototyping slower and difficult.
    • It does not have a vibrant ecosystem of users who can help, frameworks, and libraries for common tasks and applications yet.


      Before proceeding with this tutorial, you should have a basic understanding of Computer Programming terminologies in general and a good exposure to any programming language such as C, C++, or Java.

    Google Cloud Sample Resumes! Download & Edit, Get Noticed by Top Employers! Download


      To the extent Clojure was designed to allow professional programmers to write simpler, functional programs, at work, while building systems for as wide a variety of domains as are covered by Java and JavaScript, it has certainly succeeded, because that is precisely what the majority of its user community does with it. I think Clojure distills important principles acquired from programming information systems in the large, especially those around achieving loose coupling via data-driven interfaces. This fosters a unique library ecosystem with a high degree of compatibility and composability, much higher than I’ve seen with library approaches that require the coordination of code-driven constructs.

      Clojure embodies and demonstrates the continued viability of the Lisp idea, including the importance of a simple core, direct use of data, extension via libraries, and dynamic typing in delivering flexibility and reducing coupling. I would be happiest if Clojure were ultimately considered amongst languages like Common Lisp, Smalltalk, and others that I perceive as being developed by people primarily occupied with building systems, and not (or not just) designing languages.

      Clojure has introduced many professional programmers to the benefits of functional programming, and I am proud that Clojure, its community, and I have been part of the steadily increasing dialog surrounding those benefits in the programming community at large. Clojure targets real, experienced, costly programming problems like the complexity of state, the cognitive load of language features, the challenges of information, and coupling in systems. While I don’t imagine Clojure’s answers are definitive, I hope these problems and challenges continue to be a focus of system and language designers.

    Are you looking training with Right Jobs?

    Contact Us
    Get Training Quote for Free