pedestal

husayn 2020-06-28T16:02:42.277100Z

is it possible to extend a protocol defined in another library ? …. specifically TraceSpan in io.pedestal.log so that it implements <http://java.io|java.io>.Closeable ?

emccue 2020-06-28T18:45:18.277400Z

no, but you can make your own protocol to bridge the two

emccue 2020-06-28T18:46:46.278900Z

(defprotocol AsCloseable
  (-as-closeable [_]))

(extend-type java.io.Closeable
  AsCloseable
  (-as-closeable [this] this))

emccue 2020-06-28T18:47:11.279200Z

actually, err

emccue 2020-06-28T18:47:54.279500Z

its not super straight forward

emccue 2020-06-28T18:48:25.280Z

you can't actually implement a protocol on something based on it implementing another protocol

emccue 2020-06-28T18:49:14.280600Z

if you want to do that you probably would have to do a custom dispatch mechanism in some way

emccue 2020-06-28T18:51:09.282200Z

(defn as-closeable [item]
  (cond
    (satisfies? TraceSpan (type item))
    (...)
   
    (implements? Closeable item)
    item

    :else
    ...AAAA...))

emccue 2020-06-28T18:51:22.282600Z

the simplest and least extensible way would be this

emccue 2020-06-28T18:52:11.283500Z

i actually consider this a pretty big downside to protocols - they don't actually work like traits in rust or similar where you can implement a trait for anything that implements a trait

emccue 2020-06-28T19:04:42.290400Z

(def extending-protocols (atom [])

(defn register-impl-for-protocol! [protocol impl]
  (swap! extending-protocols conj [protocol impl]))

(defn as-closeable [item]
  (cond
    (instance? Closeable item)
    item

    :else
    (loop [impls @extending-protocols]
      (if-not (empty? impls)
        (let [[protocol impl] (first impls)
              remaining-impls (rest impls)]
          (if (satisfies? protocol item)
            (impl item)
            (recur remaining-impls)))
        (throw (IllegalArgumentException. (str "No Impl found for " item)))))

emccue 2020-06-28T19:06:05.291100Z

the downside here is that with-open and co won't actually work

emccue 2020-06-28T19:07:11.291600Z

I actually made a thing that I think came close to giving a general approach for this before

emccue 2020-06-28T19:07:17.291900Z

emccue 2020-06-28T19:18:23.292600Z

@husayn