Fork me on GitHub
#clojure-spec
<
2017-08-29
>
Alex Miller (Clojure team)00:08:54

there is a ticket on the way such that (s/def ::foo nil) will be sufficient to remove a spec

hmaurer10:08:19

@ikitommi I just started working with spec-tools but I am finding it a bit hard to write functions dispatching on (s/form spec) as most are wrapped in spec-tools.core/spec. Am I doing something wrong?

hmaurer10:08:58

@ikitommi ah, I just looked at https://github.com/metosin/spec-tools/blob/master/src/spec_tools/visitor.cljc and it seems you are handling that case by extracting the inner spec

ikitommi11:08:26

@U5ZAJ15P0 wrapping into spec records is unfortunate, there is https://dev.clojure.org/jira/browse/CLJ-2116 to enable runtime coercion natively. But, yes the original spec is found in :spec

hmaurer12:08:17

@ikitommi thank you! I’ll take a look. Overall great work on spec-tools by the way; it appears to solve a lot of the issues I had with clojure.spec 🙂

hmaurer12:08:23

Out of curiosity, what is the consensus regarding issues described here @ikitommi @alexmiller ? https://dev.clojure.org/jira/browse/CLJ-2116. More specifically @alexmiller , you mention > While I think some interesting problems are described in the post, I don’t agree with most of the approaches being taken there. Do you have an alternative approach to suggest? I am a beginner with clojure/clojure.spec but I did find that spec-tools answered some real needs of mine (e.g. strip extra keys when conforming a map)

Alex Miller (Clojure team)13:08:26

if you want to transform data, then transform data. why does that need to be in spec?

Alex Miller (Clojure team)13:08:43

if the selective conforming only happens at the end, why does it need to be in spec?

Alex Miller (Clojure team)13:08:08

the purpose of conforming is not transformation or coercion. it’s to tell you how a value conforms to a spec,

hmaurer13:08:01

Ah I see. So these sort of tools should be built on top of spec, not as a part of it

hmaurer13:08:37

How would you approach annotating a spec with additional data that can be used later on by utility functions?

hmaurer13:08:49

(what spec-tools does by wrapping specs in a Spec record)

Alex Miller (Clojure team)14:08:30

I would like to have arbitrary meta on specs and we have some tickets around that

Alex Miller (Clojure team)14:08:03

but barring that, specs are named with a fully-qualified name - anyone can make a registry with those keys to store arbitrary stuff

hmaurer14:08:30

@alexmiller good point; I guess those things will come more naturally to me as I get familiar with specs 🙂

tap22:08:39

@alexmiller Then this is a wrong use case example for conforming? Transforming some numbers to fizz, buzz, fizzbuzz. https://gist.github.com/stuarthalloway/01a2b7233b1285a8b43dfc206ba0036e

Alex Miller (Clojure team)22:08:03

Fizzbuzz is not a use case

tap01:08:59

Do you mean it’s a fun little problem which we can use whatever we want, right? It’s good to know for me because I misunderstood the purpose of conformer by this. Already did a csv validating and parsing using conform and additional conformers

seancorfield16:08:27

A use case we've found very valuable is using spec for conforming REST API parameters and form parameters -- which all start off as strings but we need numbers or Boolean etc. For those specs, we coerce string input to conformed values. Then we have a single step to s/conform the input map to a validated parameters map.

seancorfield16:08:26

So at the core, we'll have things like (try (Long/parseLong v) (catch Exception _ ::s/invalid)) as a named spec (predicate).

seancorfield16:08:37

I would agree with @alexmiller that coercion/transformation beyond that level is probably "doing it wrong".

ikitommi16:08:14

@seancorfield So you allow clients to send numbers as strings over JSON too?

ikitommi16:08:19

(and over EDN or Transit too)

seancorfield16:08:22

We accepted form-encoded POST bodies so it isn't always JSON.

hmaurer16:08:58

@seancorfield well, a simple case which brought me to try spec-tools was having the ability to strip all keys from a map that were not part of the spec

hmaurer16:08:25

I assume that, were I to do this myself, I would have to write a function to traverse my spec together with the data and strip keys appropriately?

seancorfield16:08:25

Why do you need to strip other keys? The only case I can think of is if you send the full hash map to a 3rd party that would object to the extra keys -- and it's safer to explicitly build the map you need at those points.

seancorfield16:08:02

If your code never uses :x in a map, why do you care that you're passed :x in the first place, is my question.

hmaurer16:08:07

precisely that; I am transacting the data to Datomic

seancorfield16:08:50

But you'd be building a namespace-qualified map specific to your schema at that point -- I wouldn't imagine the namespace-qualifier would be the same as your JSON input?

hmaurer16:08:22

no, but I have a step which namespace-qualifies my JSON input

ikitommi17:08:00

I think it's a good default to strip extra keys when reading external input. Like rest/http parameters from client

souenzzo18:08:01

Bit off, but I have a experiment that I use for example /user/%5B%3Auser%2Fuuid%20%23uuid%22123%22%5D (encoded form of /user/[:user/uuid #uuid"123"]) to avoid transformation problems (simple edn/read-string transform types). Not sure if it's a good solution/it's sacale, but it's working well on my tests.