This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-03-04
Channels
- # adventofcode (6)
- # announcements (1)
- # aws (18)
- # beginners (104)
- # boot (11)
- # cljsrn (31)
- # clojure (49)
- # clojure-dev (16)
- # clojure-europe (2)
- # clojure-greece (9)
- # clojure-houston (1)
- # clojure-italy (12)
- # clojure-nl (3)
- # clojure-spec (46)
- # clojure-uk (148)
- # clojurescript (12)
- # community-development (13)
- # core-async (7)
- # cursive (35)
- # data-science (13)
- # datomic (70)
- # events (1)
- # fulcro (22)
- # hyperfiddle (1)
- # jobs-discuss (10)
- # kaocha (3)
- # off-topic (7)
- # om (2)
- # other-languages (32)
- # parinfer (1)
- # portkey (4)
- # re-frame (3)
- # reitit (12)
- # shadow-cljs (49)
- # spacemacs (1)
- # specter (6)
- # sql (5)
- # tools-deps (58)
Is there a preferred idiom for the use of 'world information' in predicates and specs? This can occur in data validation. To clarify some, you have a data value, which you can check the 'shape/type' of via predicate and spec involving that value. Once that checks OK, a further validation requirement would be to see if what the value represents exists (in a DB or directory or ...) and is 'properly configured'. Those checks require looking outside the value so a predicate doing these checks needs more than the value. Maybe that is access to an in memory cache or a DB key or whatever. I can think of several ways to do this, but they all feel a bit off. So, is there an idom / preferred way to have that information available in predicates and specs?
@jsa-aerial My gut feeling tells me that it’s not a great idea to do side effects in specs
specs are not a great match for these kinds of validations
in general, I've seen better success with dynamically generated static specs (like running some code to register a spec with a set of allowed values pulled from a db) than with dynamic specs (which somehow close over state required to dynamically check validity in some way)
I see - I can understand that. Basically this is 'out of scope'.
pushing the limits :)
might be easier to implement as an explicit validation implemented outside of spec
Yeah, that would be one of the ways I've considered
I will say there isn't any side effecting here, but it does use / need 'outside/ world' access
Yeah, that would be one of the ways I've considered
maybe something like this would work though:
(defn foo [conn]
(let [vals (query conn)]
spec (my-custom-spec vals)]
(s/assert spec ...))
This keeps the spec entirely pureSome other ways: augment the value first with the 'key' for outside data so that the 'value' is wrapped and contains the necessary information. That's not too bad. If you have a map, augment with the 'outside key' and explicitly check the map contents (as opposed to using spec'd keys). Again, not too bad but kind of not using spec idiomatically...
Rather worse: use a dynamic var to hold the outside 'key'... This actually feels a bit dirty.
It's also worth mentioning that, strictly speaking, reading values from a DB is side-effecting because if you repeat the call, you will not necessarily get the same result. It's not mutating anything directly, but it is not a pure operation either. I think a lot of people tend to think that SELECT * FROM whatever
is "readonly" and therefore not subject to side-effects...
If nothing changes (anywhere), I don't see how it is 'side effecting' to read. The only way that would make sense is if the database were to change out from underneath you. In general that could happen, but in this case nothing of the sort is happening. Even more to the point, if it is already read and cached, nothing associated with the operations at hand is effecting anything anywhere.
That's why I said "strictly speaking" -- in the general case, where a database is a mutable thing that other processes or other threads could be updating, when you do a live read from the DB, you may get different results from different calls over time. Thus, the function doing the reading behaves as if it has side-effects because it is not pure. I was specifically excluding the case where the data is read once and cached.
(unless you're using Datomic where you can get the entire DB as an immutable value for whatever scope of request processing you want)
there are several ways to potentially spec "[a b]" - what have you tried?
could be an s/tuple, s/coll-of with :count 2, a nested s/cat
nested regexes describe the same collection
wrap s/spec around the inner s/cat
to describe a nested regex collection inside the outer regex collection
(s/cat (s/spec (s/cat ...)))
awesome! thank you @alexmiller and @borkdude!
apologies if this isn't the right place to ask - I've recently started using the replacement instrument
function from jeaye/orchestra
. I'm getting an error while generating one of my specs, the error is
Execution error - invalid arguments to orchestra.spec.test/spec-checking-fn$conform! at (test.cljc:115).
(\8 \9 \7 \9 \2 \5 \4 \2 \0 \1 \0 \8 \1 \6 \9 \3 \1 \7) - failed: string? at: [:args :digits]
I'm wondering if I'm missing something as I would expect to get a more detailed/specific error about what spec failed
@robertfrederickwarner That looks to me like it expected a string but was passed (seq s)
-- i.e., a sequence of characters instead.
Yup - that's the problem within the spec. My confusion is more that the error from orchestra isn't what I'd expect to see - looking at https://github.com/jeaye/orchestra/blob/2019.02.06-1/src/clj/orchestra/spec/test.cljc @ line 115 (the line from the error above), I'd expect to see an error prefixed with "Call to..." followed by details about the spec that failed
The problem itself - passing a sequence of chars instead of a string - is occurring within a generator for a spec so I am wondering if that is causing problems for the usual reporting
I saw some discussion of orchestra here earlier so thought I would throw it out incase anyone here recognized something obvious, I'll dig around some more but may open a bug to see what @jeaye thinks
did some further digging and tried out the standard instrument
. Orchestra was hiding the error location a little bit but otherwise returns similar to the standard error
@robertfrederickwarner So the issue exists in the upstream spec instrumentation as well?