Given a function (defn x [y] ...) and I want to verify if y fulfills some predicate, what do you suggest to use? clojure.spec? There is an example doing just this on the docs page. However, in the context of these kind of problems, malli seems to be mentioned a lot. I'm also unsure how to actually include the validation in the function, is this always done with :pre or let bindings like in the clojure.spec example? (https://clojure.org/guides/spec#_using_spec_for_validation)
please give a more specific example! We're speaking in very general terms here.
If you only need to check for a predicate, you don't need anything fancy. when-not with the predicate function and a throw might suffice. Something like this:
(defn x [y]
(when-not (number? y)
(throw (ex-info "y must be number" {:y y})))
(* y y))There's even :pre and :post assertions for simple cases.
I suggest using clojure.spec (its part of clojure so no extra libraries required) and keep the spec as simple as possible.
If you really need runtime validation, then use the example in the link you proviede.
Or define data spec for y using spec/def that uses a predicate (returns true or false. Then create a function spec using spec/fdef
Then instrument the function spec and include them in test runs (ideally with generative spec data)
Some simple examples at: https://practical.li/clojure/clojure-spec/projects/card-game/#card-game-data
heads-up, :pre takes you into the realm of assertions, which may not be what you want
https://clojurians.slack.com/archives/C03S1KBA2/p1646925751893119
I would not try to find a commonly agreed practice. If :pre works I would use it. For more complicated checks spec is often better, because it gives you a more detailed description what exactly failed. That enables you to report better error messages. But if you don't need that I would do the most simple thing, and that is :pre or when. Simple first.