Question about seq

8 views
Skip to first unread message

Sean Devlin

unread,
Jan 15, 2010, 3:26:26 AM1/15/10
to Clojure
Hey everyone,
I was working with seq today, and I was wondering why I got a certain
result.

user=> (seq [])
nil

Why is nil returned, instead of an empty sequence?

Sean

Laurent PETIT

unread,
Jan 15, 2010, 3:50:23 AM1/15/10
to clo...@googlegroups.com
Hey,

I guess because a sequence is not a datastructure.
If there is nothing to iterate over via 'first or 'next, then it's nil.

And an "empty sequence" is precisely that: nil.

In my point of view, a sequence is more like a "functional iterator":
calling first on it will always return the same value, calling next on
it will return either nil if we are at the end, either a new seq ...

Hope I'm clear and also correct,

--
Laurent


2010/1/15 Sean Devlin <francoi...@gmail.com>:

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

Stephen C. Gilardi

unread,
Jan 15, 2010, 4:01:01 AM1/15/10
to clo...@googlegroups.com
On Jan 15, 2010, at 3:26 AM, Sean Devlin wrote:

user=> (seq [])
nil

Why is nil returned, instead of an empty sequence?

It's fundamental to Clojure's seq abstraction that every seq has a first. There is no such thing as an empty seq. If you call the seq function on an empty collection, it can't return a seq because that (hypothetical) seq would have no first. Instead seq returns nil meaning "no seq".

(seq x) (used as a predicate) is the canonical way in Clojure to ensure that x contains at least one item.

Rich's video about Clojure sequences at iTunes and on blip.tv provides more details and rationale.

--Steve

Adrian Cuthbertson

unread,
Jan 15, 2010, 4:02:23 AM1/15/10
to clo...@googlegroups.com
Hi Sean,

The background to this lies in the implementation of lazy sequences -
seq returns an implementation of ISeq for the data structure in
question - nil when there are no elements in the structure. Have a
look at http://clojure.org/sequences and also http://clojure.org/lazy
which gives the full reasoning behind this. It clarifies when to use
next and when to use rest (lazy sequences).

-Hth, Adrian.

Stephen C. Gilardi

unread,
Jan 15, 2010, 1:02:12 PM1/15/10
to clo...@googlegroups.com

On Jan 15, 2010, at 4:01 AM, Stephen C. Gilardi wrote:

> On Jan 15, 2010, at 3:26 AM, Sean Devlin wrote:
>
>> user=> (seq [])
>> nil
>>
>> Why is nil returned, instead of an empty sequence?
>

> There is no such thing as an empty seq.

This was true at one time, but isn't true after the changes to Clojure that added LazySeq.

For example:

user=> (def e (filter even? [1]))
#'user/e
user=> (type e)
clojure.lang.LazySeq ; e is a lazy seq
user=> (seq? e)
true ; e is a seq
user=> (empty? e)
true ; e is empty
user=> e
() ; e prints as an empty seq

> (seq x) (used as a predicate) is the canonical way in Clojure to ensure that x contains at least one item.

This is still true (and is mentioned in the doc for empty?)

user=> (seq e)
nil ; seq e is nil

--Steve

Reply all
Reply to author
Forward
0 new messages