On Thu, Jul 7, 2011 at 4:48 PM, octopusgrabbus <[email protected]> wrote:
> What does this mean exactly?
>
> sequential?
> function
>
> Usage: (sequential? coll)
>
> Returns true if coll implements Sequential
>
> from 
> http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/sequential

Seems to test for ordered Clojure collections. I get true for seqs,
lists, and vectors, but not strings, arrays, java.util.LinkedLists,
maps, or sets. So unordered collections and ordered Java collections
seem to be excluded.

There's also seq? which excludes vectors and coll? which includes maps
and sets. All exclude non-Clojure seqables such as LinkedLists,
strings, and arrays.

None return true for nil.

Unfortunately there isn't a built-in predicate function corresponding
to "will seq work on this?". This inherently works:

(defn seqable? [x]
  (try
    (seq x)
    (catch Exception _ false)))

producing (seq x) if doesn't throw an exception, false if it does.
It's a bit icky but does the job, and has a few useful properties:

(if-let [a (seqable? x)] ...)

runs the body with a bound to (seq x) if x is seqable and not empty.

(if (false? (seqable? x)) ...)

catches non-seqables.

But it doesn't quite work as a straight predicate if you want nil and
empty inputs treated as seqable. You can change that by just adding
"true" on a line by itself after (seq x), but then you have to call
seq a second time if you want the seq result, which you usually do.
Changing the (seq x) to (if-let [a (seq x)] a ()) will return a truthy
value for all objects interpretable as a seq but will turn all empties
into a non-nil empty list instead of nil.

Another form avoids the icky exception hack and doesn't call seq on
its argument:

(defn array? [x] (and x (contains? (set (.getName (.getClass x))) \[)))

(defn seqable? [x]
  (or
    (coll? x)
    (nil? x)
    (instance? java.util.Collection x)
    (instance? java.util.Map x)
    (instance? java.util.Set x)
    (string? x)
    (array? x)))

It does do a bit of a hack to test for arrays and it breaks if seq is
extended in the future to work with anything it currently won't
accept.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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

Reply via email to