Back
extend-protocol (clj)
(source)macro
(extend-protocol p & specs)
Useful when you want to provide several implementations of the same
protocol all at once. Takes a single protocol and the implementation
of that protocol for one or more types. Expands into calls to
extend-type:
(extend-protocol Protocol
AType
(foo [x] ...)
(bar [x y] ...)
BType
(foo [x] ...)
(bar [x y] ...)
AClass
(foo [x] ...)
(bar [x y] ...)
nil
(foo [x] ...)
(bar [x y] ...))
expands into:
(do
(clojure.core/extend-type AType Protocol
(foo [x] ...)
(bar [x y] ...))
(clojure.core/extend-type BType Protocol
(foo [x] ...)
(bar [x y] ...))
(clojure.core/extend-type AClass Protocol
(foo [x] ...)
(bar [x y] ...))
(clojure.core/extend-type nil Protocol
(foo [x] ...)
(bar [x y] ...)))
Examples
viebel/klipse
(ns clojure.core.rrb-vector.interop
(:require [clojure.core.rrb-vector.protocols
:refer [PSliceableVector -slicev
PSpliceableVector -splicev]]
[clojure.core.rrb-vector.rrbt :refer [-as-rrbt]]))
(extend-protocol PSliceableVector
cljs.core/PersistentVector
(-slicev [v start end]
(-slicev (-as-rrbt v) start end))
(extend-protocol PSpliceableVector
cljs.core/PersistentVector
(-splicev [v1 v2]
(-splicev (-as-rrbt v1) v2))
pedestal/pedestal
(ns io.pedestal.http.jetty.container
(:require [io.pedestal.http.container :as container]
[clojure.core.async :as async])
(:import (java.nio.channels ReadableByteChannel)
(java.nio ByteBuffer)
(org.eclipse.jetty.server Response)))
(extend-protocol container/WriteNIOByteBody
org.eclipse.jetty.server.Response
(write-byte-channel-body [servlet-response ^ReadableByteChannel body resume-chan context]
(let [os ^org.eclipse.jetty.server.HttpOutput (.getHttpOutput servlet-response)]
(.sendContent os body (reify org.eclipse.jetty.util.Callback
(succeeded [this]
(.close body)
(async/put! resume-chan context)
(async/close! resume-chan))
(failed [this throwable]
(.close body)
(async/put! resume-chan (assoc context :io.pedestal.impl.interceptor/error throwable))
(async/close! resume-chan))))))
(write-byte-buffer-body [servlet-response ^ByteBuffer body resume-chan context]
(let [os ^org.eclipse.jetty.server.HttpOutput (.getHttpOutput servlet-response)]
(.sendContent os body (reify org.eclipse.jetty.util.Callback
(succeeded [this]
(async/put! resume-chan context)
(async/close! resume-chan))
(failed [this throwable]
(async/put! resume-chan (assoc context :io.pedestal.impl.interceptor/error throwable))
(async/close! resume-chan)))))))
thheller/shadow-cljs
(ns shadow.remote.runtime.cljs.js-builtins
(:require
[goog.object :as gobj]
[clojure.core.protocols :as p]))
(extend-protocol p/Datafiable
;; FIXME: this is kind of a bad idea
;; can't do this for all objects, since none of the CLJS types implement this
;; protocol either. the protocol dispatch will end up using object
;; FIXME: this could detect CLJS types to some extent
;; or should it just implement the protocols for the types?
object
(datafy [o]
(if-not (identical? (.-__proto__ o) js/Object.prototype)
o
(with-meta
(->> (gobj/getKeys o)
(reduce
(fn [m key]
(assoc! m key (gobj/get o key)))
(transient {}))
(persistent!))
jonase/eastwood
(ns testcases.unusednss3
(:require [clojure.core.protocols :as protocols]
[clojure.core.reducers :as reducers]
[clojure.data :as data]
[clojure.java.io :as io]
[clojure.reflect :as reflect]))
(extend-protocol reducers/CollFold
String
(coll-fold [coll n combinef reducef] nil))
mikera/core.matrix
Indexes are intended to be used to specify elements, ranges or sub-arrays of core.matrix arrays.
As such they can be considered as a 1D vector of integer values."
(:require [clojure.core.matrix.protocols :as mp]
[clojure.core.matrix.macros :refer [error]])
(:import [clojure.lang IPersistentVector]))
(extend-protocol mp/PIndexImplementation
(Class/forName "[J")
(index? [m]
true)
(index-to-longs [m]
m)
(index-to-ints [m]
(int-array m))
(index-from-longs [m xs]
xs)
(index-from-ints [m xs]
(long-array xs))
(index-coerce [m a]
(mp/index-to-longs a)))
(extend-protocol mp/PIndexImplementation
(Class/forName "[I")
(index? [m]
true)
(index-to-longs [m]
(long-array m))
(index-to-ints [m]
m)
(index-from-longs [m xs]
(int-array xs))
(index-from-ints [m xs]
xs)
(index-coerce [m a]
(mp/index-to-ints a)))
(extend-protocol mp/PIndexImplementation
IPersistentVector
(index? [m]
(every? integer? m))
(index-to-longs [m]
(long-array m))
(index-to-ints [m]
(int-array m))
(index-from-longs [m xs]
(vec xs))
(index-from-ints [m xs]
(vec xs))
(index-coerce [m a]
(cond
(mp/index? a)
(mp/persistent-vector-coerce a)
(== 1 (long (mp/dimensionality a)))
(vec (mp/index-to-longs a))
:else
(error "Can't make a 1D index from array of shape " (mp/get-shape a)))))