Is there a Clojure compile-time tool to check if a record or type actually implements a protocol it claims to?
Asked Answered
A

1

10

Seems the Clojure compiler doesn't do this by default : Does the Clojure compiler check if records and types implement protocols?

Any, say, Lein plugins that do this?

Attach answered 15/8, 2015 at 17:56 Comment(0)
S
4

The amazing core.typed introduces "an optional type system for Clojure", as you can see on their official website.

Specifically you may want to use their own defprotocol macro (from core.typed wiki) :

Protocol definitions should use clojure.core.typed/defprotocol whose syntax is reminiscent of defprotocol and typed fn:

(defprotocol IUnifyWithLVar
  (unify-with-lvar [v u :- LVar s :- ISubstitutions] :- (U ISubstitutions Fail)))

Polymorphic protocols are supported:

(defprotocol [a b] Lens
   (-fetch [l x :- a] :- b)
   (-putback [l x :- a v :- b] :- a))

Once installed, you run it via leiningen with lein typed check. The obvious downside is that you have to annotate your code. This is the cost to pay to increase the safety of your code by using static type checking.

You may also be interested by the functions satisfies?, and instance?.

Systemize answered 15/8, 2015 at 22:25 Comment(7)
Would satisfies? or instance? verify that some interface or protocol is implemented thoroughly? Only in combination with core.typed?Hereinafter
They are separate things completely. core.typed is a type checker, while the two others are functions and must be called at run-time (satisfies? is useful for protocols, not instant? but I included it for completeness). Again they are completely independant.Systemize
OK, the reason I ask is that neither of those functions as far as I know tell you if some object implements a specific interface or protocol method.Hereinafter
(satisfies? protocol x) ;; Returns true if x satisfies the protocol I'm not sure what you're saying.Systemize
that will return true even if the object does not implement any of the methods of the protocolHereinafter
To be honest I was looking for something other than core.typed. Initially I liked the idea of it, as it implied light-weight typing only when you wanted it. But it seems I have to explicitly type ALL my functions; which is something I definitely don't want to have to do. I only want to check protocols.Attach
yes @Hereinafter , satisfies? only seems to test if the record SAYS that it implements the protocol, not if it ACTUALLY has all the named methods.Attach

© 2022 - 2024 — McMap. All rights reserved.