Re: check if something can be coerced to a seq

2011-01-17 Thread Stuart Sierra
The problem with a seq-able? predicate is that the definition of what is 
seq-able is often context-dependent. `seq` works on Strings, but you 
probably don't want `flatten` to turn a String into a sequence of 
characters.

-S
clojure.com

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: check if something can be coerced to a seq

2011-01-17 Thread Jürgen Hötzel
2011/1/17 Stuart Sierra the.stuart.sie...@gmail.com

 The problem with a seq-able? predicate is that the definition of what is
 seq-able is often context-dependent. `seq` works on Strings, but you
 probably don't want `flatten` to turn a String into a sequence of
 characters.


Good point. There is no static atom/listp distinction in Clojure. Still a
predicate function for can yield a seq is missing, to provide a flexible
flatten implementation like:

(defn my-flatten
  ([pred coll]
 (mapcat (fn [p] (if (pred (first p)) (mapcat my-flatten p) p))
 (partition-by pred coll)))
  ([coll]
 (my-flatten sequential? coll)))

Jürgen

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: check if something can be coerced to a seq

2011-01-16 Thread Ken Wesson
On Sun, Jan 16, 2011 at 6:22 AM, Jürgen Hötzel juer...@hoetzel.info wrote:
 Hi,
 I came across this issue while implementing a lazy, efficient flatten that
 also uses the whole sequence abstraction (flatten java arrays).
 The problem with (seq x) is, that it will throw an Exception if called on
 something, that cannot be coerced to sequence, so I just used sequencial?
 like the current implementation of flatten:
 (defn my-flatten [coll]
   (mapcat (fn [p] (if (sequential? (first p)) (mapcat my-flatten p) p))
           (partition-by sequential? coll)))
 But this will obviously fail  to flatten anything that doesn't
 implement clojure.lang.Sequential (like java.arrays).

Unfortunately, right now that's a big gap in the clojure.core
functionality. It's quick to fix, though the fix is a bit of a hack as
it uses the exception-throwing behavior of (seq x). On the plus side
this guarantees that it meets its contract.

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

(def m-seq seqable?)

(defn seqable-ns? [x]
  (if-not (instance? java.lang.String x) (seqable? x)))

(def m-seq-ns seqable-ns?)

Anything seqable is returned unchanged by seqable? and m-seq, which
return nil rather than throw if the thing is not seqable. The two
names for the same function are just to improve code readability:
seqable? for use as a predicate and m-seq for uses like

(if-let [x (m-seq foo)] (do-something-with x))

The -ns versions differ only in that they pretend Strings aren't
seqable, for those fairly common cases where you want to treat strings
as atomic rather than as character sequences; for instance if you're
probing a data structure made of nested colls and wish to regard whole
strings as leaf nodes in the traversal instead of their individual
characters.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en