Fork me on GitHub
#clojure-spec
<
2019-04-27
>
kommen10:04:45

playing around with spec-alpha2, I was wondering if there is a way to make s/conform of an s/select only return keys of a map which are actually specified in the select.

kommen10:04:04

(s/def :foo/id string?)
(s/def :foo/text1 string?)
(s/def :foo/text2 string?)
(s/def ::foo (s/schema [:foo/id :foo/text1 :foo/text2]))
(s/def ::foo-only-text1 (s/select ::foo [:foo/id :foo/text1]))

(s/conform ::foo-only-text1 {:foo/id "bar" :foo/text1 "t1" :foo/text2 "t2"})
;; => #:foo{:id "bar", :text1 "t1", :text2 "t2"}

Alex Miller (Clojure team)16:04:30

It’s not working this way at the moment but select over a closed schema should throw invalid on that case

Alex Miller (Clojure team)16:04:57

The close stuff is going to get completely overhauled though so current api will change

dominicm14:04:55

I was curious about this, could you share what the current thinking is? Even with the disclaimer of it being heavy WIP?

Alex Miller (Clojure team)14:04:06

rather than the stateful api (which was intended to be similar to instrument), will be more op-specific, and actually more generic than just "closing", will open up some api space for other kinds of checking variants

Alex Miller (Clojure team)14:04:38

so, new options on valid?, conform, assert, etc - anything with checking

πŸ‘ 4
dominicm14:04:09

Sounds really interesting. Looking forward to seeing how much leverage this provides.

ikitommi08:04:40

checking variants like runtime transformations / coercion? or just validating? anyway, generic sounds great. πŸ‘

metametadata15:05:01

> so, new options on valid?, conform, assert, etc - anything with checking it looks like it will create friction for adopting closed maps in defn-spec and other libs which don't know about new options in the methods and rely on the fact that every spec itself describes everything needed for validation

Alex Miller (Clojure team)15:05:09

that's something defn-spec will have to reckon with. function specs themselves are going to go through significant changes and making an integrated defn+function spec syntax is in scope.

metametadata15:05:42

thanks. fwiw, this is the typical way I add specs to protocol methods using defn-spec at the moment (`sp` here contains custom spec helpers):

(:require [common.logic.specs :as specs]
            [spec-plus.core :as sp]
            [clojure.spec.alpha :as s]
            [defn-spec.core :as ds]))

(defprotocol Protocol
  (-fetch-places [_ postal]))

(ds/defn-spec fetch-places
  {::s/args (sp/pos any? ::specs/postal)
   ::s/ret  (sp/seq-of ::specs/place)}
  [this postal]
  (-fetch-places this postal))

dominicm15:05:12

I guess there's a open question of whether the function level is the right place for deciding closedness. Maybe the other flags will clarify this.

metametadata15:05:53

yes, it's interesting to see how function specs will play with closed maps. and speaking of that, this is how I use closed maps in functions currently:

(ds/defn-spec build-and-push
  {::s/args (sp/pos ::component
                    (sp/speced-keys :req-un [::path ::image-id ::tag]))} ; sp/speced-keys implements a closed s/keys spec
  [component {:keys [path image-id tag]}]
...

dominicm15:05:56

I'm suggesting that maybe it's up to the caller sometimes whether to apply certain constraints.

Alex Miller (Clojure team)15:05:31

these flags will probably be available on calls like instrument or check so you could supply those constraints that way

metametadata15:05:33

would be cool if it allowed to spec a function in such a way that some args are closed and some are not, e.g. (foo <closed-map> <integer> <open-map>)

dominicm15:05:38

That sounds like an important filter.

Alex Miller (Clojure team)16:05:47

the planned api will allow that

Alex Miller (Clojure team)16:05:42

well, on a per-spec basis that is. if you want to use the same spec in both modes in a single context, not sure about that (or whether that's even a real use case)

dominicm17:05:40

Hmm, merging an old-user with new-user where the new user is coming over the wire and needs to be locked down, but old-user is from the db?

ikitommi08:04:40

checking variants like runtime transformations / coercion? or just validating? anyway, generic sounds great. πŸ‘