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 clojure@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to