One point to appreciate about this approach is the flexibility in only worrying about the relevant pieces. In my case, I may be worrying about whether a continuous variable has been tagged "datetime", requiring additional processing steps. Merely checking for such tags allows the input data to implicitly direct the flow of the program, reducing the coupling between data and specific processing implementations.
(def Customer {:customer-id s/Int, :address-id s/Int}
(def ProcessedCustomer (merge Customer {:external-id s/Int}))Not saying it isn't useful, in fact I have a project in which this would be a very good fit and I might even implement it there.
This looks like a contract library, which I assume already exists in Clojure. It'd be interesting to see what's unique about this implementation, if anything.
(type! :Point (requires :x :y))
(some->> points
(all-built-like :Point)
(map color)
(map embellish))
To keep it simple, as in the first example of the whirlwind tour, we could use: (def Point {:x s/Any :y s/Any})
(some->> points
(s/validate [Point])
(map color)
(map embellish))
It's good that structural-typing does not use macros, instead building ontop of specter which is pretty cool. So is there a performance enhancement?It's clear that one should use structural-typing where an expertise with specter has been attained, Not sure when else it's the best choice.
Speaking as one who is trying to use more functional languages and starting to love Elm.