metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.51k stars 212 forks source link

Arity error in function schema #601

Open respatialized opened 2 years ago

respatialized commented 2 years ago

Issue

A function schema produces an error due to overlapping arities when I attempt to use a seqex as the schema for one of the function's input arguments.

Reproducing the bug

Attempting to create the following schema throws an error.

(m/schema
 [:function
  [:=> [:cat [:schema [:* :int]]] :any]
  [:=> [:cat [:schema [:* :int]] :boolean] :any]])
{:type :malli.core/duplicate-arities,
    :message :malli.core/duplicate-arities,
    :data
    {:infos
     [{:min 0, :arity :varargs, :input [:cat [:schema [:* :int]]], :output :any}
      {:min 1,
       :arity :varargs,
       :input [:cat [:schema [:* :int]] :boolean],
       :output :any}]}}

Further information

This error occurs in spite of the fact that the input arities are independently both valid and produce the expected values when used as generators:

(mg/generate [:cat [:schema [:cat [:* :int]]] :boolean])
;; => ((-2 2096836 3803 45 -49393) false)
(mg/generate [:cat [:schema [:cat [:* :int]]]])
;; => ((-1709 -2289 -38 3962880 -8 -948 13075997 77734 -16118422 635358 2 -1 -1))

@ikitommi suggested that m/-regex-min-max might be contributing to the error:

Looks like :schema has a bug related to m/-regex-min-max :


(m/-regex-min-max
(m/schema
 [:cat [:schema [:* :int]]]))
; => {:min 0} 

Previously reported on the #malli channel on the Clojurians Slack.

bbqbaron commented 1 month ago

EDIT: Just use :tuple, which does work since it explicitly describes a collection, eg [:=> [:cat [:tuple :int :int]] :int]

I ran into this just now too:

(defn my-fn [x] 1)
(malli.core/=> my-fn [:=> [:cat [:cat :int :int]] :int])
(malli.instrument/instrument!)
(my-fn [1 2])
; :malli.core/invalid-arity
(my-fn 1 2)
; ------ WARNING - :fn-arity -----------------------------------------------------
;  Resource: <eval>:1:1
;  Wrong number of args (2) passed to engine/my-fn
; --------------------------------------------------------------------------------

I.e., calling it with two arguments gets past Malli, but triggers normal arity validation.

I also think it's regex min-maxing believing that nesting :cat doesn't affect the length of the sequence. This isn't true of nested vectors, so maybe it's a more general conceptual issue? One element with two elements in it isn't two elements.