title: testing if something is an empty list
body: <p>Which way should I prefer to test if an object is an empty list in Clojure? Note that I want to test just this and not if it is empty as a sequence. If it is a "lazy entity" (<code>LazySeq</code>, <code>Iterate</code>, ...) I don't want it to get <code>realized?</code>.</p>
  
  <p>Below I give some possible tests for <code>x</code>.</p>
  
  <pre class="lang-clj prettyprint-override"><code>;0
  (= clojure.lang.PersistentList$EmptyList (class x))
  
  ;1
  (and (list? x) (empty? x))
  
  ;2
  (and (list? x) (zero? (count x)))
  
  ;3
  (identical? () x)
  </code></pre>
  
  <p>Test 0 is a little low level and relies on "implementation details". My first version of it was <code>(instance? clojure.lang.PersistentList$EmptyList x)</code>, which gives an <code>IllegalAccessError</code>. Why is that so? Shouldn't such a test be possible?</p>
  
  <p>Tests 1 and 2 are higher level and more general, since <code>list?</code> checks if something implements <code>IPersistentList</code>. I guess they are slightly less efficient too. Notice that the order of the two sub-tests is important as we rely on short-circuiting.</p>
  
  <p>Test 3 works under the assumption that every empty list is the same object. The tests I have done confirm this assumption but is it guaranteed to hold? Even if it is so, is it a good practice to rely on this fact?</p>
  
  <p>All this may seem trivial but I was a bit puzzled not finding a completely straightforward solution (or even a built-in function) for such a simple task.</p>
  
  <hr>
  
  <h1>update</h1>
  
  <p>Perhaps I did not formulate the question very well. In retrospect, I realized that what I wanted to test was if something is a non-lazy empty sequence. The most crucial requirement for my use case is that, <strong>if it is a lazy sequence</strong>, it does not get realized, i.e. <strong>no thunk gets forced</strong>.</p>
  
  <p>Using the term "list" was a little confusing. After all what is a list? If it is something concrete like <code>PersistentList</code>, then it is non-lazy. If it is something abstract like <code>IPersistentList</code> (which is what <code>list?</code> tests and probably the correct answer), then non-laziness is not exactly guaranteed. It just so happens that Clojure's current lazy sequence types do not implement this interface.</p>
  
  <p>So first of all I need a way to test if something is a lazy sequence. The best solution I can think of right now is to use <code>IPending</code> to test for laziness in general:</p>
  
  <pre><code>(def lazy? (partial instance? clojure.lang.IPending))
  </code></pre>
  
  <p>Although there are some lazy sequence types (e.g. chunked sequences like <code>Range</code> and <code>LongRange</code>) that do not implement <code>IPending</code>, it seems reasonable to expect that lazy sequences implement it in general. <code>LazySeq</code> does so and this is what really matters in my specific use case.</p>
  
  <p>Now, relying on short-circuiting to prevent realization by <code>empty?</code> (and to prevent giving it an unacceptable argument), we have:</p>
  
  <pre><code>(defn empty-eager-seq? [x] (and (not (lazy? x)) (seq? x) (empty? x)))
  </code></pre>
  
  <p>Or, if we know we are dealing with sequences like in my case, we can use the less restrictive:</p>
  
  <pre><code>(defn empty-eager? [x] (and (not (lazy? x)) (empty? x)))
  </code></pre>
  
  <p>Of course we can write safe tests for more general types like:</p>
  
  <pre><code>(defn empty-eager-coll? [x] (and (not (lazy? x)) (coll? x) (empty? x)))
  (defn empty-eager-seqable? [x] (and (not (lazy? x)) (seqable? x) (empty? x)))
  </code></pre>
  
  <p>That being said, the recommended test 1 also works for my case, thanks to short-circuiting and the fact that <code>LazySeq</code> does not implement <code>IPersistentList</code>. Given this and that the question's formulation was suboptimal, I will accept Lee's succinct answer and thank Alan Thompson for his time and for the helpful mini-discussion we had with an upvote.</p>