Fork me on GitHub
#clojure-spec
<
2019-11-27
>
doesntmeananything11:11:21

what's the best way to spec a nested map? Say, I have a customer map that looks something like this:

{:email ""
   :password "horsecabbagetruck"
   :first-name "John"
   :last-name "Doe"
   :organization
   {:organization/settings
    {:organization.setting/send-requests? true
     :organization.setting/receive-requests? true}
    :organization/name "Acme"}}
how would you go about validating these nested fields? Simply write a couple of spec registries and then collect them in an entity map? So you'd do:
(s/def ::customer (s/keys :req-un [::email ::password ::first-name ::last-name ::organization]))
and ::organization would be specced to have the namespaced nested data? I'm a bit unsure on how to proceed since the official guide doesn't really have explicit examples of nested data as far as I can see

vemv11:11:41

I'd say you're going in the right direction try the pattern you have posted, and verify if you are getting the desired validations. Else post the exact failed attempt here

vlaaad12:11:08

this is an example of nested data structures: players/deck in a game

doesntmeananything12:11:50

cool, thanks for the help, guys

bbloom22:11:45

mini-survey: are folks using https://github.com/danielcompton/defn-spec or something similar? how do you like/dislike it?

vemv00:11:47

I authored https://github.com/nedap/speced.def and we're happy with it at work. Since it compiles to a clojure/script defn it has zero limitations or new syntax, guaranteed. it doesn't preclude creating generic/reusable specs: you can author those and still use them here. It has no :fn equivalent (only :`args` :ret ones), but honestly I have yet to see how that is not equivalently achieved with the occasional :pre condition.

vemv00:11:33

I haven't campaigned much about it so far, but I plan to post something to #news-and-articles later this week :)

seancorfield22:11:28

@bbloom I don't use it -- I often put fdefs in a separate namespace in libraries so they are optional and the code can then run on older Clojure versions.

seancorfield22:11:10

(and I don't like that syntax so I wouldn't want to use it even when I would put fdefs above the function for which they exist)

bbloom22:11:58

thanks for the thoughts - i’m not using anything like it yet b/c i like to kinda use the primitives until i grok them fully and then and only then abstract more

seancorfield22:11:58

Those limitations alone would make it non-viable for most of my fdef use cases I think.

bbloom22:11:17

i’m still trying to figure out where/when to utilize spec

seancorfield22:11:52

https://corfield.org/blog/2019/09/13/using-spec/ is about how we use it at World Singles Networks

👀 4
bbloom22:11:57

i’ve been doing a lot of TypeScript for work lately, and all the inline annotations are simultaneously: laborious, helpful, and hurtful

bbloom23:11:19

thanks @seancorfield, that all makes sense to me - to some extent i’m trying to decide how far to do w/ development time checking

bbloom23:11:36

my current thinking is basically just-in-time specing, where i spec stuff as part of my debugging process and leave the specs around for future use

didibus23:11:13

I've got a library like that in the works, probably 80% done at this point. Don't know if or when I'll finish it. But my focus is on fn specs, since those are the painful ones to write in my opinion. As well as multi-arity, var-args, et all. Those are the hard ones to write, so my DSL intends to make these way quicker to spec, as to encourage more spec writing. Right now the machinery attaches itself as metadata on defns, so it also is compatible with older Clojure versions.

didibus23:11:34

Some edge cases can be tricky, which is why it's taking me longer than I initially thought to put together.

didibus23:11:52

But I do think I'd write more fn specs if defn had a easier syntax for writing them. So that's what I'm trying to achieve. I also recognize it is hard to come up with one that is simpler but not limited. Which is why there probably isn't an official one.