Thanks Christopher Grand. I really like your scaffold .. would be extremely
handy .. Like david suggested .. it would be a perfect candidate for
inclusion in the clojure.repl

Regarding your bimap implementation, in terms of complexity, I feel, it will
be linear in the number of elements, when accessing the pair via the value
.. Is that true?

Sunil

On Tue, Nov 16, 2010 at 2:36 PM, Christophe Grand <christo...@cgrand.net>wrote:

> You can implement your own, prettu easily with deftype.
> However it can be tedious to track every methods, so we need a repl helper
> function to scaffold the code for us.
>
> (defn scaffold [iface]
>   (doseq [[iface methods] (->> iface .getMethods
>                             (map #(vector (.getName (.getDeclaringClass %))
>
>                                     (symbol (.getName %))
>                                     (count (.getParameterTypes %))))
>                             (group-by first))]
>     (println (str "  " iface))
>     (doseq [[_ name argcount] methods]
>       (println
>         (str "    "
>           (list name (into ['this] (take argcount (repeatedly
> gensym)))))))))
>
> user=> (scaffold clojure.lang.IPersistentMap)
>   clojure.lang.IPersistentMap
>     (assoc [this G__441 G__442])
>     (without [this G__443])
>     (assocEx [this G__444 G__445])
>   java.lang.Iterable
>     (iterator [this])
>   clojure.lang.Associative
>     (containsKey [this G__446])
>     (assoc [this G__447 G__448])
>     (entryAt [this G__449])
>   clojure.lang.IPersistentCollection
>     (count [this])
>     (cons [this G__450])
>     (empty [this])
>     (equiv [this G__451])
>   clojure.lang.Seqable
>     (seq [this])
>   clojure.lang.ILookup
>     (valAt [this G__452 G__453])
>     (valAt [this G__454])
>   clojure.lang.Counted
>     (count [this])
> nil
>
> Now you need to remove the duplicates (count and assoc), wrap everything in
> a deftype form and implement it:
> (including a new protocol fn to reverse a bidi map)
>
> (defprotocol ReversibleMap
>   (rmap [m]))
>
> (defn- rdissoc [d r v]
>  (if-let [[_ k] (find r v)] (dissoc d k) d))
>
> (deftype Bimap [^clojure.lang.IPersistentMap direct reverse]
>   Object
>   (hashCode [x]
>     (.hashCode direct))
>   (equals [x y]
>     (.equals direct y))
>   clojure.lang.IPersistentMap
>     (without [this k]
>       (Bimap.
>         (dissoc direct k)
>         (rdissoc reverse direct k)))
>     (assocEx [this k v]
>       (if (or (contains? direct k) (contains? reverse v))
>         (throw (Exception. "Key or value already present"))
>         (assoc this k v)))
>   java.lang.Iterable
>     (iterator [this]
>       (.iterator direct))
>   clojure.lang.Associative
>     (assoc [this k v]
>       (Bimap.
>         (assoc (rdissoc direct reverse v) k v)
>         (assoc (rdissoc reverse direct k) v k)))
>     (containsKey [this k]
>       (contains? direct k))
>     (entryAt [this k]
>       (find direct k))
>   clojure.lang.IPersistentCollection
>     (cons [this x]
>       (if-let [[k v] (and (vector? x) x)]
>         (assoc this k v)
>         (reduce (fn [m [k v]] (assoc m k v)) this x)))
>     (empty [this]
>       (.empty direct))
>     (equiv [this x]
>       (.equiv direct x))
>   clojure.lang.Seqable
>     (seq [this]
>       (seq direct))
>   clojure.lang.ILookup
>     (valAt [this k else]
>       (direct k else))
>     (valAt [this k]
>       (direct k))
>   clojure.lang.Counted
>     (count [this]
>       (count direct))
>   ReversibleMap
>     (rmap [this]
>       (Bimap. reverse direct)))
>
> (defn bimap [& kvs]
>   (reduce (fn [m [k v]] (assoc m k v)) (Bimap. {} {}) (partition 2 kvs)))
>
> Some quick tests:
> user=> (assoc (bimap :a 1 :b 2) [:c 3] [:d 4] [:e 5])
> {[:e 5] nil, [:c 3] [:d 4], :b 2, :a 1}
> user=> (assoc (bimap :a 1 :b 2) :c 3 :d 4 :e 5)
> {:e 5, :d 4, :c 3, :b 2, :a 1}
> user=> (assoc (bimap :a 1 :b 2) :c 3 :d 2 :e 5)
> {:e 5, :d 2, :c 3, :a 1}
> user=> (dissoc *1 :d)
> {:e 5, :c 3, :a 1}
> user=> (rmap *1)
> {5 :e, 3 :c, 1 :a}
> user=> (assoc *1 2 :c)
> {2 :c, 5 :e, 1 :a}
>
> hth,
>
> Christophe
>
>
>  On Tue, Nov 16, 2010 at 8:16 AM, Sunil S Nandihalli <
> sunil.nandiha...@gmail.com> wrote:
>
>>  A bimap is a map where each elements of the pair can be used as key to
>> access it..
>> Sunil.
>>
>>
>> On Tue, Nov 16, 2010 at 12:44 PM, Sunil S Nandihalli <
>> sunil.nandiha...@gmail.com> wrote:
>>
>>> Hello everybody,
>>>
>>> Is there something like a bimap in clojure? I know I can have two regular
>>> hash-maps .. but I was wondering if there is a better implementation..?
>>>
>>>  a similar implementation in c++ is
>>>
>>> http://beta.boost.org/doc/libs/1_41_0/libs/bimap/doc/html/index.html
>>>
>>> Thanks,
>>> Sunil.
>>>
>>
>>  --
>> 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<clojure%2bunsubscr...@googlegroups.com>
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>
>
> --
> Professional: http://cgrand.net/ (fr)
> On Clojure: http://clj-me.cgrand.net/ (en)
>
> --
> 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<clojure%2bunsubscr...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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