On Jun 3, 2009, at 12:53 PM, CuppoJava wrote:
Is there a function that will return true iff calling seq on it's argument will not throw an error? I thought it was seq?, but (seq? [1 2 3]) returns false.
Such a function might be called "seqable?". As far as I know it doesn't exist currently. I've wanted it in the past as well.
The "seq" function is implemented in Java as RT.seq:
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
which calls RT.seqFrom:
static ISeq seqFrom(Object coll){
if(coll instanceof Seqable)
return ((Seqable) coll).seq();
else if(coll == null)
return null;
else if(coll instanceof Iterable)
return IteratorSeq.create(((Iterable) coll).iterator());
else if(coll.getClass().isArray())
return ArraySeq.createFromObject(coll);
else if(coll instanceof String)
return StringSeq.create((String) coll);
else if(coll instanceof Map)
return seq(((Map) coll).entrySet());
else {
Class c = coll.getClass();
Class sc = c.getSuperclass();
throw new IllegalArgumentException("Don't know how to create
ISeq from: " + c.getSimpleName());
}
}
From that we could derive isSeqable in Java as
static public bool isSeqable(Object coll){
return
(coll instanceof ISeq) ||
(coll instanceof Seqable) ||
(coll == null) ||
(coll instanceof Iterable) ||
(coll.getClass().isArray()) ||
(coll instanceof String) ||
(coll instanceof Map);
}
(ASeq and LazySeq both implement ISeq so their two tests can be
collapsed into one.)
I've checked in a Clojure version to clojure.contrib.core:
user=> (doc seqable?)
-------------------------
clojure.contrib.core/seqable?
([x])
Returns true if (seq x) will succeed, false otherwise.
nil
user=>
The one critique I have of this is that one might expect (seqable? x)
to return true only if (instance? clojure.lang.Seqable x) returns
true. I think the name seqable? is ideal otherwise though, so I used it.
--Steve
smime.p7s
Description: S/MIME cryptographic signature
