Hi Konrad,
On 22 Okt., 18:07, "[EMAIL PROTECTED]"
<[EMAIL PROTECTED]> wrote:
> But assume I wanto to provide two implementations for such an
> interface, in two separate namespaces. Can I then write client code
> that will work with either one? I would have to pass it the namespace
> as an argument. I wonder if the client code would still remain
> readable. Perhaps some clever macro would help...
Ok stupid example (don't think to much about the sense, just for
demonstration): you use a message digest to identify things.
The interface is easy: it's a single function which you pass a
thing and it tells you the id. Let's call it identify
Say, you have two implementations one using MD5, one using SHA1.
I see the following scenarios:
- The user wants to choose the implementation. So provide an
identical interface:
(ns com.identity.MD5)
(defn identify [x] (do-md5-things-to x))
and
(ns com.identity.SHA1)
(defn identify [x] (do-sha-things-to x))
The user can then use:
(use 'com.identity.MD5)
(identify x)
or he can assign an alias:
(require '[com.identity.MD5 :as identificator])
(identificator/identify x)
In both cases you don't have to change the code. Just import
the different namespace.
- You want to choose the implementation, transparent for the user.
Provide a facade in com.identity forwarding the request or have
another structure for your source:
(if (some-condidition-holds)
(require '[com.identity.MD5 :as digest])
(require '[com.identity.SHA1 :as digest]))
(defn identity
[x]
(digest/identify x))
or replay with the same idea for your lib internally:
(defn identity
[x]
(digest/do-digest-things-to x))
> Next, assume that I need to use two or more implementations of my
> interface in parallel, in the same code, just as I can use lists and
> vectors indifferently with client routines using the seq interface. I
> guess that is impossible using the "interface-by-documentation"
> approach, right?
For this you probably want multimethods, since the implementations
are "active" at the same time. So you need some way to distinguish
what you got passed.
> A related question concerns the interfaces that Clojure already uses:
> ISeq and Number, for example. Can I implement my own data structure in
> Clojure that supports the ISeq interface? Can I implement a new number
> type and have it work with +, -, etc.?
I'm not sure about the numbers but for ISeq (and other interfaces)
one can use proxy.
(defn rev-vector-seq
[v]
(when (< 0 (count v))
(proxy [clojure.lang.ISeq] []
(seq [] this)
(first [] (peek v))
(rest [] (rev-vector-seq (pop v))))))
Hope this helps.
Sincerely
Meikel
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---