Fork me on GitHub
#clojure-spec
<
2021-04-15
>
sam05:04:32

I could use some guidance on using clojure.spec to validate input arguments to a function. Here’s some context: • I am debating instrumenting with fdef vs. using :pre and :post conditions. • The function is internal to the app and the argument values are completely under the control of the programmer (i.e. there is no validation of external data going on). I was initially leaning toward instrumenting with fdef because I see this as a check for program correctness rather input validation. It should be safe to turn this check off in production with no change in behavior. But I want the instrumentation to be turned on by default during development and turned off by default in production. I can imagine ways to achieve that, but the fact that I couldn’t find any mention of a typical pattern for doing that (e.g. my understanding is that assert is set up to be easily enabled/disabled in a blanket manner) made me think I might be missing something.

sam05:04:46

Another thing I should mention is that I have no intention of ever testing this function with generative tests. It’s not a good fit for generative testing.

vemv10:04:26

> I was initially leaning toward instrumenting with fdef because I see this as a check for program correctness rather input validation. what's this? (I can interpret it in two different ways)

sam14:04:19

Yeah, that’s fair. this = “this solution I’m designing”, not this = “instrumenting with fdef”.

👍 3
vemv14:04:00

If ease of turning on/off is the main concern, perhaps I'd go for fdef because it's the default choice, and toggling it globally, and both for inputs and outputs seems relatively easy with https://github.com/jeaye/orchestra There are reasons beyond toggling ease why some people might prefer assert to instrumentation. https://github.com/fulcrologic/guardrails or https://github.com/nedap/speced.def (disclaimer: I authored it) and probably a couple more libraries favor it. There's no fixed truth in the topic, but in absence of other concerns I'd probably 'start small'.

sam14:04:46

@U45T93RA6 Thanks a ton! I need to digest this more and check out orchestra. Off the top of my head, my only concern is that I usually like to be a little wary about adding new dependencies if I don’t have to.

Alex Miller (Clojure team)12:04:38

Are you talking about clojure.core/assert or s/assert? Seems like the latter would be good here

sam14:04:17

Thanks! Somehow I missed s/assert , I think you’re right. Maybe s/assert in a :pre condition…

Alex Miller (Clojure team)14:04:05

I'd put it in the mainline

Alex Miller (Clojure team)14:04:38

s/assert in mainline code is designed so that it can be compiled completely out of the program via https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/*compile-asserts*

sam15:04:49

Okay, thank you! I really appreciate the guidance.

Franco Gasperino22:04:28

Hello. Where i have several defined and registered predicates, can i compose them in this state?

;; contrived example
(s/def ::string-starts-with-an-a? (s/and string? #(string/starts-with? % "a")))
(s/def ::not-an-apple? #(not= "apple" %))
(s/def ::starts-with-an-a-but-not-an-apple? (s/and ::string-starts-with-an-a? ::not-an-apple?))

Franco Gasperino22:04:20

predicate composing after registration

Franco Gasperino22:04:37

disregard the above. my forms had not been evaluated, thus the error received was entirely my doing