extend-protocol doesn't work on deftype-fn backed types
Problem
When a deftype is backed by a custom type via :deftype-fn (e.g. SciMap in babashka), extend-protocol on that type doesn't work.
The root cause is that type-impl returns :sci.impl.protocols/reified for ICustomType instances (rather than the specific type symbol like user.MyCache), so the defmethod registered by extend-protocol for the specific type never matches.
Reproduction
(defprotocol Extra (extra [this]))
(extend-protocol Extra
MyCustomType
(extra [this] :it-works))
(extra (->MyCustomType ...))
;; => No implementation of method: :extra of protocol: #'user/Extra found for: :sci.impl.protocols/reified
Analysis
In sci.impl.types/type-impl:
SciTypeInstance is checked first → returns specific type symbol (e.g. user.Foo) — extend-protocol works
ICustomType is checked second → returns :sci.impl.protocols/reified — extend-protocol doesn't match
For the standard SciType path, inline protocol impls are registered as defmethods keyed on the specific type symbol. extend-protocol also registers defmethods for that symbol, so both work.
For custom types (via :deftype-fn), inline protocol impls go through the :reified defmethod which delegates to ICustomType.getMethods(). But extend-protocol registers a defmethod for the specific type symbol, which never fires because type-impl returns :reified.
Possible fix
Make custom type instances also implement SciTypeInstance (or otherwise return a specific type symbol from type-impl), then register a per-type defmethod that delegates to getMethods(). This would let both inline impls and extend-protocol coexist.
This would also open the door to unifying the standard SciType path and the custom type path, since both would use methods-map + per-type defmethod delegation.
extend-protocol doesn't work on deftype-fn backed types
Problem
When a
deftypeis backed by a custom type via:deftype-fn(e.g. SciMap in babashka),extend-protocolon that type doesn't work.The root cause is that
type-implreturns:sci.impl.protocols/reifiedforICustomTypeinstances (rather than the specific type symbol likeuser.MyCache), so the defmethod registered byextend-protocolfor the specific type never matches.Reproduction
Analysis
In
sci.impl.types/type-impl:SciTypeInstanceis checked first → returns specific type symbol (e.g.user.Foo) — extend-protocol worksICustomTypeis checked second → returns:sci.impl.protocols/reified— extend-protocol doesn't matchFor the standard
SciTypepath, inline protocol impls are registered as defmethods keyed on the specific type symbol.extend-protocolalso registers defmethods for that symbol, so both work.For custom types (via
:deftype-fn), inline protocol impls go through the:reifieddefmethod which delegates toICustomType.getMethods(). Butextend-protocolregisters a defmethod for the specific type symbol, which never fires becausetype-implreturns:reified.Possible fix
Make custom type instances also implement
SciTypeInstance(or otherwise return a specific type symbol fromtype-impl), then register a per-type defmethod that delegates togetMethods(). This would let both inline impls andextend-protocolcoexist.This would also open the door to unifying the standard SciType path and the custom type path, since both would use methods-map + per-type defmethod delegation.