Fork me on GitHub
#clojure-spec
<
2018-02-26
>
devn00:02:44

are s/describe or s/form what I want to use here, or am I missing something obvious?

devn00:02:54

I'd like to peek at req and opt to pass them into a pull query

devn00:02:52

@seancorfield that'll get me the spec objects by name, but not in a way that's easy to pluck out the req/opt

devn00:02:50

i have a feeling im just missing something obvious, maybe in how i define the :req to begin with. Is it possible for me to use a spec as the arg to :req I wonder

seancorfield00:02:02

Yeah, right now you'd have to get the form for each spec and then walk them.

seancorfield00:02:21

Since the keys part could be embedded deep inside a spec...

gfredericks00:02:48

doesn't somebody mention a yet-to-exist spec spec every time this comes up?

devn00:02:20

something loosely like:

(s/def ::the-keys [::a ::b])
(s/def ::the-map :req ::the-keys)

seancorfield00:02:00

Alex says they're looking at ways to make it easier to build specs programmatically but it's not there yet.

devn00:02:47

err, well, when it's a set, I can at least do (s/form ::the-keys) and get back #{::a ::b}, it's just that I can't use it in the s/keys form

seancorfield00:02:22

clojure.spec is a wonderful concrete example of how macros don't compose đź‘€

devn01:02:51

im not complaining. i think there's probably a solution im missing here, let me try to be a bit more clear on what i want to do. I have a spec which says that ::a and ::b are required. I need some value holder that can be used both in the spec definition: (s/keys :req ...) and a pull query (d/q '{:find [(pull ?blah ?the-qualified-keys) :in [$ ?the-qualified-keys]] ...} db the-qualified-keys)

devn01:02:35

err, i could relax that second part and say I'm not sure if that's possible. if it isn't, what kind of clever solutions are there? I suppose I could generate the spec and a corresponding def, for instance, so i don't have to manually keep modifications to either place consistent.

seancorfield01:02:02

What we've done at work is to define a spec with keys, build any more complex specs on top of that, then get the spec form itself, parse out the :req [...] part and pull the keys from that to use elsewhere. So the base spec was the "system of record" and we derived other stuff from it.

seancorfield01:02:26

It's kind of icky but it works, given what we have available right now. It seems like the path of least resistance.

devn01:02:17

maybe (s/describe) is good enough for what i want to do here, the structure of it just felt a little wonky to me: (keys :req [:foo/a :foo/b]), so i need to do something like (apply hash-map (rest (s/describe ::the-map))) or whatever

seancorfield01:02:10

Hmm, we use s/form... what is s/describe?

devn01:02:18

roughly the same deal

seancorfield01:02:40

Ah, an "abbreviated" form as data...

devn01:02:07

form: (clojure.spec.alpha/keys :req [:foo/a :foo/b]) describe: (keys :req [:foo/a :foo/b])

devn01:02:32

i'm surprised it's not a map, but perhaps there are Reasons™ why that I don't understand

gfredericks01:02:59

getting a map isn't hard though: (apply hash-map (rest thing))

devn01:02:16

fair point

devn01:02:51

it gave me that "is this a hint that i shouldn't be using it like this?" feeling

gfredericks01:02:47

probably just a hint that it's not done yet

mpenet13:02:20

@alexmiller any details/insight about how could spec meta data look like in the future?

mpenet13:02:59

another question while I am at it: was it ever considered to implement (s/def ::foo ::bar) via clojure.core/derive? I would personally find it quite interesting with that form, you can leverage ancestors/isa? etc

alexmiller13:02:11

Not sure if Rich ever considered that.

mpenet13:02:18

does that sound like something desirable in your opinion?

alexmiller13:02:20

Don’t know. The example above I would consider aliasing, not a hierarchy. The notion of derivation with respect to s/keys (containership) is interesting though for additive aggregations.

mpenet13:02:41

we use that on a small lib to add metadata to specs, we then can just say spec ::x derives from another and add useful little utils on top of that that can optionally fetch all the metadata from the ancestors and merge them for instance.

mpenet13:02:55

yes exactly why I am asking

ghadi20:02:04

I filed https://dev.clojure.org/jira/browse/CLJ-2327 just to capture that slowdown

alexmiller20:02:19

I think probably replacing the big set with a char int numeric check would probably help a lot

ghadi20:02:46

I don't think so @alexmiller -- it's OOMing which means some extra retention

ghadi20:02:08

I think we could remove the chars entirely and have a smaller example

alexmiller20:02:32

if you replace the :atom branch with something like (defn atom-char? [c] (let [i (int c)] (or (<= 48 i 57) (<= 65 i 90) (<= 97 i 122)))), I think you’ll find it doesn’t have the issue

ghadi20:02:45

trying it...

ghadi20:02:50

it does not help at all @alexmiller

alexmiller20:02:02

helped for me

ghadi20:02:14

did you (s/+ atom-char?)

ghadi20:02:20

mine is still running

alexmiller20:02:40

oh, maybe I just did atom-char?

ghadi20:02:59

pretty sure it's the s/alt and s/+ combo

alexmiller20:02:00

not (s/+ atom-char?)