Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying Clojure for Java Developers
  • Table Of Contents Toc
Clojure for Java Developers

Clojure for Java Developers

close
close
Clojure for Java Developers

Clojure for Java Developers

Overview of this book

We have reached a point where machines are not getting much faster, software projects need to be delivered quickly, and high quality in software is more demanding as ever. We need to explore new ways of writing software that helps achieve those goals. Clojure offers a new possibility of writing high quality, multi-core software faster than ever, without having to leave your current platform. Clojure for Java developers aims at unleashing the true potential of the Clojure language to use it in your projects. The book begins with the installation and setup of the Clojure environment before moving on to explore the language in-depth. Get acquainted with its various features such as functional programming, concurrency, etc. with the help of example projects. Additionally, you will also, learn how the tooling works, and how it interacts with the Java environment. By the end of this book, you will have a firm grip on Clojure and its features, and use them effectively to write more robust programs.
Table of Contents (9 chapters)
close
close
8
Index

Using a REPL

One of the main advantages of Clojure (and Lisp) is interactive development, the REPL is the base of what can be achieved with interactive programming, it allows you to connect to a running VM running Clojure and execute or modify code on the fly.

There is a story about how NASA was able to debug and correct a bug on a $100 million piece of hardware that was 100 million miles away (http://www.flownet.com/gat/jpl-lisp.html).

We have that same power with Clojure and Leiningen and invoking it is very simple, you just need a single command:

lein repl

This is what you'll get after running the preceding command:

Using a REPL

Let's go into a bit more detail, as we can see we are running with the following programs:

  • Java 8
  • Clojure 1.6.0

We can also get some nice suggestions on how to see documentation, source, Javadoc, and previous errors.

The nREPL protocol

One particular thing that is important to note is the nREPL protocol; Someday it might grant us the power to go into a machine running 100 million miles away.

When you fire up your REPL, the first thing you see is:

nREPL server started on port 55995 on host 127.0.0.1 - nrepl://127.0.0.1:55995
REPL-y 0.3.5, nREPL 0.2.6

What it is saying is that there's a Clojure process running an nREPL server on port 55995. We have connected to it using a very simple client that allows us to interact with the Clojure process.

The really interesting bit is that you can connect to a remote host just as easily; let's try attaching an REPL to the same process by simply typing the following command:

lein repl :connect localhost:55995

Most IDEs have a good integration with Clojure and most of them use this exact mechanism, as clients that work a little more intelligently.

Hello world

Now that we are inside the REPL, (any of the two) let's try writing our first expression, go on and type:

"Hello world"

You should get back a value from the REPL saying Hello world, this is not really a program, and it is the Hello world value printed back by the print phase of the REPL.

Let's now try to write our first Lisp form:

(println "Hello world")

This first expression looks different from what we are used to, it is called an S-expression and it is the standard Lisp way.

There are a couple of things to remember with S-expressions:

  • They are lists (hence, the name, Lisp)
  • The first element of the list is the action that we want to execute, the rest are the parameters of that action (one two three).

So we are asking for the string Hello world to be printed, but if we look a bit closer at the output, as shown in the following screenshot, there is a nil that we weren't expecting:

Hello world

The reason for this is that the println function returns the value nil (Clojure's equivalent for null) after printing Hello world.

Note

In Clojure, everything has a value and the REPL will always print it back for you.

REPL utilities and conventions

As we saw, the Leiningen nREPL client prints help text; but how does that work? Let's explore some of the other utilities that we have.

Try each of them to get a feeling of what it does with the help of the following table:

Function

Description

Sample

doc

Prints out a function's docstring

(doc println)

source

Prints a function's source code, it must be written in Clojure

(source println)

javadoc

Open the javadoc for a class in the browser

(javadoc java.lang.Integer)

Let's check how these functions work:

user=> (javadoc java.util.List)
;; Should open the javadoc for java.util.List

user=> (doc doc)
-------------------------
clojure.repl/doc
([name])
Macro
  Prints documentation for a var or special form given its name
nil

user=> (source doc)
(defmacro doc
"Prints documentation for a var or special form given its name"
  {:added "1.0"}
  [name]
  (if-let [special-name ('{& fn catch try finally try} name)]
    (#'print-doc (#'special-doc special-name))
    (cond
      (special-doc-map name) `(#'print-doc (#'special-doc '~name))
      (find-ns name) `(#'print-doc (#'namespace-doc (find-ns '~name)))
      (resolve name) `(#'print-doc (meta (var ~name))))))
nil

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

What you are seeing here is metadata pertaining to the doc function; Clojure has the ability to store metadata about every function or var you use. Most of the Clojure core functions include a doc string and the source of the function and this is something that will become very handy in your day to day work.

Besides these functions, we also get easy access to the latest three values and the latest exceptions that happened in the REPL, let's check this out:

user=> 2
2
user=> 3
3
user=> 4
4
user=> (* *1 *2 *3) ;; We are multiplying over here the last three values
24 ;;We get 24!
user=> (/ 1 0) ;; Let's try dividing by zero
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
user=> *e
#<ArithmeticException java.lang.ArithmeticException: Divide by zero>

user=> (.getMessage *e)
"Divide by zero"

Note

*e gives you access to the actual plain old Java exception object, so you can analyze and introspect it at runtime.

You can imagine the possibilities of being able to execute and introspect code with this, but what about the tools that we are already used to? How can we use this with an IDE?

Let's check now how to create a new Clojure project, we'll use Leiningen from the command line to understand what is happening.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Clojure for Java Developers
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon