Uploaded image for project: 'Clojure'
  1. CLJ-2218

[spec] Improving consistency of explain-data for instrument/macroexpand-check


    • Type: Improvement
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects versions: Release 1.9
    • Fix versions: None
    • Labels:
    • Patch:



      If you instrument a function, you may get a spec error like the following:

      (defn f [x] (inc x))
      (s/fdef f
        :args (s/cat :x (s/and integer? even?))
        :ret (s/and integer? odd?))
      (f 3)
      ;; ExceptionInfo Call to #'user/f did not conform to spec:
      ;; In: [0] val: 3 fails at: [:args :x] predicate: even?
      ;; :clojure.spec.alpha/spec  #object[clojure.spec.alpha$regex_spec_impl$reify__1200
       0x19b3f9a "clojure.spec.alpha$regex_spec_impl$reify__1200@19b3f9a"]
      ;; :clojure.spec.alpha/value  (3)
      ;; :clojure.spec.alpha/args  (3)
      ;; :clojure.spec.alpha/failure  :instrument
      ;; :clojure.spec.test.alpha/caller  {:file "form-init3240393046310519022.clj", :lin
      e 1, :var-scope user/eval1413}
      ;; clojure.core/ex-info (core.clj:4725)
      (ex-data *e) 
      ;; {:clojure.spec.alpha/problems
      ;;   [{:path [:args :x],
      ;;     :pred clojure.core/even?,
      ;;     :val 3,
      ;;     :via [],
      ;;     :in [0]}],
      ;;  :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__1200 0x19b3f9a "clojure.spec.alpha$regex_spec_impl$reify__1200@19b3f9a"],
      ;;  :clojure.spec.alpha/value (3),
      ;;  :clojure.spec.alpha/args (3),
      ;;  :clojure.spec.alpha/failure :instrument,
      ;;  :clojure.spec.test.alpha/caller {:file "form-init3240393046310519022.clj", :line 1, :var-scope user/eval1413}} 

      As you can see,

      • the explain-data has a regex (ie. the spec for the args of f) in it as ::s/spec
      • each problem contains :args in their :path

      These facts can cause a confusion to spec error reporters because the spec for the args of f ((s/and integer? even?)) has no subspec corresponding to the key :args (I believe :path should only contains keys that is a clue to indicate which subspec to be chosen from a spec).

      Possible resolutions

      To resolve this confusing situation and improve the consistency of explain-data for instrument check, I think there are two options as follows:

      • Solution 1. removing :args from :path
      • Solution 2. modifying explain-data for instrument check so that they have fspec (rather than :args of it) as ::s/spec

      Personally, I prefer Solution 2. since adding fspec in explain-data makes it possible to provide richer error information to *explain-out* implementors.

      The same goes for macroexpand-check.




            • Assignee:
              sohta Shogo Ohta
            • Votes:
              1 Vote for this issue
              1 Start watching this issue


              • Created: