Skip to content

0.15.0.1

Compare
Choose a tag to compare
@camsaul camsaul released this 06 Oct 20:39
· 26 commits to master since this release
687a0ac

Methodical 0.15.0 adds support for defmethod arglist validation, improved error messages, a bug fix, and ten new utility functions.

GitHub Milestone: https://github.com/camsaul/methodical/milestone/12

Macroexpansion-time defmethod arglist arity validation

Methodical 0.15.0 adds support for validating the the number of args if defmethod arglists. If you have a three-arg multimethod and try to write a defmethod for it that takes only two args, get an error message right away! (Issue #59, PR #130)

:defmethod-arities

A set of allowed/required arities that defmethod forms are allowed to have. defmethod forms must have arities that
match all of the specified :defmethod-arities, and all of its arities must be allowed by :defmethod-arities:

(m/defmulti ^:private mf
  {:arglists '([x]), :defmethod-arities #{1}}
  keyword)

(m/defmethod mf :x [x] x)
;; => ok

(m/defmethod mf :x ([x] x) ([x y] x y))
;; => error: {:arities {:disallowed #{2}}}

(m/defmethod mf :x [x y] x y)
;; => error: {:required #{1}, :disallowed #{2}}

:defmethod-arities must be a set of either integers or [:> n] forms to represent arities with & rest
arguments, e.g. [:>= 3] to mean an arity of three or-more arguments:

;; methods must have both a 1-arity and a 3+-arity
(m/defmulti ^:private mf
  {:arglists '([x] [x y z & more]), :defmethod-arities #{1 [:>= 3]}}
  keyword)

(m/defmethod mf :x ([x] x) ([x y z & more] x))
;; => ok

(m/defmethod mf :x [x y] x)
;; => error: {:arities {:required #{1 [:>= 3]}, :disallowed #{2}}}

When rest-argument arities are used, Methodical is smart enough to allow them when appropriate even if they do not
specifically match an arity specified in :defmethod-arities:

(m/defmulti ^:private mf
  {:arglists '([x y z & more]), :defmethod-arities #{[:>= 3]}}
  keyword)

(m/defmethod mf :x
  ([a b c] x)
  ([a b c d] x)
  ([a b c d & more] x))
;; => ok, because everything required by [:>= 3] is covered, and everything present is allowed by [:>= 3]

Improved Error Messages

  • Ambiguous primary method errors should tell you WHAT method has the ambiguity (Issue #126)

Bug Fixes

  • Var metadata for multimethods created by defmulti doesn't get updated when metadata on symbol changes (Issue #129)

New utility functions

  • Added utility higher-level functions for creating common dispatch functions: dispatch-on-first-arg, dispatch-on-first-two-args, dispatch-on-first-three-args, and dispatch-on-first-four-args (Issue #16, PR #132)
  • Added is-default-effective-method? and is-default-primary-method? utility functions (Issue #38, PR #134)
  • Added unprefer-method, remove-all-preferences, unprefer-method!, and remove-all-preferences! functions for removing preferences from multimethods (Issue #7, PR #135)