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
-~----------~----~----~----~------~----~------~--~---

Reply via email to