I am learning the concept of sequence
and nil
in Clojure. This was the result of a small experimentation.
1:6 user=> (first '())
nil
1:7 user=> (rest '())
()
1:8 user=> (first (rest '()))
nil
Does this mean that '() is actually a sequence of nils?
If you want to test whether the "rest" of a collection is empty, use next
.
user> (next '(foo bar))
(bar)
user> (next '())
nil
user> (doc next)
-------------------------
clojure.core/next
([coll])
Returns a seq of the items after the first. Calls seq on its
argument. If there are no more items, returns nil.
"nil-punning" (treating an empty collection/seq and nil
as the same thing) was removed last year in favor of fully-lazy sequences. See here for a discussion leading up to this change.
first
and rest
are functions that apply to a logical structure (a seq
) and not on the linked cons structure of a list (as in other lisps).
Clojure defines many algorithms in terms of sequences (seqs). A seq is a logical list, and unlike most Lisps where the list is represented by a concrete, 2-slot structure, Clojure uses the ISeq interface to allow many data structures to provide access to their elements as sequences.
http://clojure.org/sequences
The behavior is a result of the definition of the function and not determined by the primitive structure of the data.
No - an empty list is not the same as an infinite sequence of nils
This is relatively easy to show. Suppose we have:
(def infinite-nils (repeat nil)) ; an infinite lazy sequence of nils
(def empty-list '()) ; an empty list
They have different numbers of elements:
(count infinite-nils) => doesn't terminate
(count empty-list) => 0
Taking from them:
(take 10 infinite-nils) => (nil nil nil nil nil nil nil nil nil nil)
(take 10 empty-list) => ()
If you call seq on them you get
(seq inifinite-nils) => sequence of infinite nils
(seq empty-list) => nil
The confusion in the original can largely be resolved by understanding the following facts:
(seq '())
returns nil, as does (seq (rest '()))
(first (rest '()))
is nil.Also learning Clojure.
For empty sequences, rest
returns a sequence for which seq
returns nil
.
That's why you get that behavior.
I assume this is to simplify recursing on sequences until they are empty, and probably other smartypants reasons...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With