Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Spec by

Is it expected that st/instrument can be enabled for all fdef'ed functions (e.g., (st/instrument))? For example, say a library has a public API calling some internal functions that are spec'ed with fdef's. If the fdefs are included in the published library, is it expected that calls to those internal functions calls should pass their fdef'ed specs even though they are internal? Take the below example code.

(ns my-lib.impl
  (:require
    [clojure.spec.alpha :as s]))

(defn- do-internal-thing
  [x]
  x)

(s/fdef do-internal-thing
  :args (s/cat :x number?))

(ns my-lib.api
  (:require
    [clojure.spec.alpha :as s]
    [my-lib.impl :as impl]))

(defn do-thing
  [y]
  (impl/do-internal-thing "oops"))

If I call the api function do-thing, I will get an instrumentation exception on the call to impl/do-internal-thing. Should users of Spec's instrumentation be expected to filter out some set of fdef'ed functions and pass that filtered list to st/instrument or is this something the library should be expected to maintain? Maybe libraries should not include fdefs on internal functions?

1 Answer

+1 vote
by
selected by
 
Best answer

Yes, it is expected that fdefs on private functions can be instrumented (it's just a var wrapper after all).

I think it may be a good idea to have specs on internal/private functions in an independent namespace so its use can be controlled via load (lib can load it for testing, users would not and would likely not even know it existed).

Additionally, I think it's usually a good idea to instrument a set of fdef'ed functions in st/instrument (with st/enumerate-namespace as a helper).

...