On Mon, Nov 9, 2009 at 8:28 PM, John Harrop <jharrop...@gmail.com> wrote:
> Why not: > > static public Object contains(Object coll, Object key){ > if(coll == null) > return F; > else if(coll instanceof Map) > return ((Map) coll).containsKey(key) ? T : F; > else if(coll instanceof IPersistentSet) > return ((IPersistentSet) coll).contains(key) ? T : F; > else if(key instanceof Number && (coll instanceof String || > coll.getClass().isArray())) { > int n = ((Number) key).intValue(); > return n >= 0 && n < count(coll); > } > return F; > } > > instead? > Sort of answered my own question: user=> (ancestors (class [1 2 3])) #{clojure.lang.Associative java.lang.Comparable java.lang.Iterable clojure.lang.IPersistentVector java.util.RandomAccess clojure.lang.IMeta clojure.lang.IObj clojure.lang.IPersistentCollection clojure.lang.Sequential clojure.lang.IFn clojure.lang.Seqable java.util.concurrent.Callable java.io.Serializable clojure.lang.Streamable clojure.lang.AFn clojure.lang.Obj clojure.lang.IPersistentStack clojure.lang.Counted java.util.Collection java.lang.Object java.util.List clojure.lang.Reversible clojure.lang.APersistentVector java.lang.Runnable} Looks like Associative doesn't inherit Map for some reason. I wonder why not? There's no reason for it not to, with IPersistentVector for example functioning as a Map<Integer,Object>. Since none of the Map modifying operations would be supported it's not like someone could add a new mapping to [1 2 3] like {5000000, "foo"} or {-12, 'bar} or something like that that would screw things up. On the other hand, static public Object contains(Object coll, Object key){ if(coll == null) return F; else if(coll instanceof Map) return ((Map) coll).containsKey(key) ? T : F; else if(coll instanceof IPersistentSet) return ((IPersistentSet) coll).contains(key) ? T : F; else if(key instanceof Number && (coll instanceof String || coll.getClass().isArray() || coll instanceof Collection)) { int n = ((Number) key).intValue(); return n >= 0 && n < count(coll); } return F; } catches IPersistentVector and friends with strings and arrays in clause 3, and neatly handles maps, sets, and list-like collections in three cleanly-separated clauses, instead of mixing maps and some list-like collections. In the meantime, the main thing still missing from Clojure is a convenient queue. Lists and vectors both add and remove efficiently only at one end, and at the same end for add and remove in both cases. Doubly-linked lists can't be made persistent without massive problems, but laziness has its own issues: (defn queue-peek [q] (first q)) (defn queue-pop [q] (rest q)) (defn queue-push [q obj] (concat q [obj])) (let [q (reduce queue-push nil (range 1000000))] (reduce (fn [_ q] (queue-pop q)) nil q)) #<CompilerException java.lang.StackOverflowError (NO_SOURCE_FILE:0)> --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---