Fork me on GitHub
#clojure-spec
<
2019-05-12
>
denik02:05:39

Is anyone aware of a library that is designed to transform data based on a spec or similar? cc @alexmiller

seancorfield03:05:15

Resist the temptation tho' @denik -- spec is not intended to be used to drive transformations 🙂

denik15:05:30

@alexmiller @seancorfield @ikitommi to be clear, I'm not looking to coerce data, rather I want to to give it a richer shape (e.g. places -> names / sequential -> associative). I have a concise place-based syntax like [:user/add [:post 5 :authors] {:id 10 :user/name "Eve"}] that I want to turn into

{:op :user/add
 :path [:post 5 :authors]
 : entity {:id 10 :user/name "Eve"}}
This would be easy in vanilla clojure but there are some gotchas, for example path is optional. With other edge cases writing that in vanilla clojure would get ugly fast. Spec's s/? + conform (or similar) seem like a perfect fit. So if it's not conform, I'm wondering if there is a straightforward approach to parse and unparse while leveraging specs?

stathissideris15:05:24

@denik s/conform would work for this, but I’ve seen people advising against using it

alexmiller17:05:19

cond-> is great for optional stuff

alexmiller17:05:31

I’d just use core stuff

denik18:05:37

@alexmiller not for parsing

alexmiller19:05:02

there are libs for data structure parsing like https://github.com/cgrand/seqexp that do the "parsing" of data

denik15:05:28

thanks! unfortunately clj only

ikitommi20:05:06

Puzzled. I would have said that s/conform would have been a perfect tool (without any add-onns) for parsing just that example. What are the downsides of using spec for parsing?

alexmiller21:05:25

conform is fine for parsing

alexmiller22:05:01

Request above is for additional transformation and enhancement of the result

denik15:05:39

conforming/parsing + generation of a spec for the parsed result (comformed shape) so that it can be checked in other function invocations as well as fspecs. I would find this very useful: 1. sparse data comes in from a request, e.g. [:user/add [:post 5 :authors] {:id 10 :user/name "Eve"}] 2. conform data to use names instead of indexes/places=>

{:op :user/add
 :path [:post 5 :authors]
 :entity {:id 10 :user/name "Eve"}}
3. use a derived spec of the conformed value from (2) to check validity of the value as it is updated throughout the program