32
votes

Forgive me if I'm being obtuse, but I'm a little bit confused by the documentation about nil in Clojure. It says:

nil has the same value as Java null.

Does this mean that they're the same thing or are they different somehow? And does a NullPointerException mean that a Java null was encountered or would I also get this if nil was encountered?

2

2 Answers

46
votes

From the Clojure source code, lang/LispReader.java:

static private Object interpretToken(String s) throws Exception{
    if(s.equals("nil"))
        {
        return null;
        }

From lang/RT.java:

static public void print(Object x, Writer w) throws Exception{
    {
    ...
    if(x == null)
        w.write("nil");

So nil is Clojure's representation for the underlying platform's null. nil shows up nowhere else in the Java source for Clojure. The only difference between nil and null is that one is Clojure and the other is Java, but they're essentially aliases, converted back and forth seamlessly as needed by the reader and printer when going from Clojure to Java to Clojure.

Yeah, nil can cause NullPointerExceptions. Try calling any Java method on nil, you'll get an NPE, e.g.

(.tostring nil)

The Clojure source code is pretty easy to read when it comes to things like this, give it a look.

25
votes

From Learning Clojure

"In most Lisp dialects, there is a value semi-equivalent to Java null called nil. In Clojure, nil is simply Java's null value, end of story."

Since Clojure compiles to java bytecode, it sounds like any reference to nil is just a null object reference in the underlying JVM. Your NPEs from executing Clojure are the result of accessing nil.