This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-24
Channels
- # admin-announcements (2)
- # beginners (46)
- # boot (8)
- # cider (29)
- # cljs-dev (45)
- # cljsjs (10)
- # cljsrn (13)
- # clojure (60)
- # clojure-dev (5)
- # clojure-greece (1)
- # clojure-ireland (4)
- # clojure-mexico (6)
- # clojure-poland (3)
- # clojure-quebec (3)
- # clojure-russia (8)
- # clojure-spec (89)
- # clojure-uk (70)
- # clojurescript (84)
- # cursive (4)
- # datomic (7)
- # devcards (1)
- # dirac (2)
- # emacs (11)
- # hispano (10)
- # jobs (13)
- # keechma (34)
- # lein-figwheel (4)
- # luminus (19)
- # off-topic (2)
- # om (78)
- # onyx (6)
- # parinfer (1)
- # planck (82)
- # proton (2)
- # re-frame (10)
- # reagent (23)
- # ring-swagger (5)
- # spacemacs (2)
- # specter (24)
- # spirituality-ethics (122)
- # untangled (13)
How do you spec protocol functions? Is it the same as spec-ing a regular function? (I haven't actually tried it yet...)
I tried to spec a multimethod using fdef
a few days ago and it didn't work but I didn't have time to figure out why
@bsima: Read this issue for some information about spec and protocols http://dev.clojure.org/jira/browse/CLJ-1941 (regarding instrumentation)
How do I best write a generator for :args
? It seems like even if I use (gen/cat <sequence-generating generators>)
it generates a sequence that is then passed to :args
as the first argument, instead of "splicing" it into the macro/function call.
@jannis Is it not sufficient for you to write individual generators? Do you have many dependencies between your args?
@akiel: This is my example: https://gist.github.com/Jannis/51ebdd54e10074fd9c574a54dd8421c9
The args are fairly flexible and somehow what gets generated for name
and & forms
is not quite what it should be. Perhaps my :args
spec is wrong (thinking var args perhaps need special treatment)?
Even if I just use (s/cat :name ::command-name)
and drop the & forms
argument in the macro, check-var
complains with "Wrong number of args (1) passed to: command/defcommand"
. Something there is odd.
Actually, this is a Clojure + ClojureScript macro, which will just pass on the arguments to a function that does the actual work. I could move the spec to that function instead.
but speccing macros is an interesting feature on its own - but check-var might simply not work with it
I simply don’t know. I’ll hit this if a spec my first macro. But I have currently none.
Moving the spec to the function and turning the var-args into a (s/cat :name ... :forms (s/spec (s/cat :description ...)))
subspec structure does the job 🙂
Question about the direction of namespaced keywords:
With Clojurescript (Om appears to be pushing namespaced keywords) on the front end, specs in the middle, and Datomic on the end, namespaced keywords feel natural.
But if you’re working with a Javascript front-end, that doesn’t support them. And a SQL database on the other. What’s one to do in the middle if you want to leverage specs?
Just :req-un everything?
Or create translation layers across the board?
:req-un
works fine - the only thing you loose is automatic validation of all keys even if not present in req or opt
Makes sense. I’ve hesitated on spec for fear that they can’t live in “the real world” (a non-full-Clojure stack environment).
even in clojure itself - nobody can change existing apis - so un-namespaced keywords will be still there
K, thanks @akiel.
@kendall.buchanan: I’m working on making namespaced keyword support in java.jdbc
a lot easier. In the upcoming 0.6.2 release you’ll be able to specify a :qualifier "foo"
option on calls to get :foo/col-name
back from all queries. I need to figure out the final story for what happens if you push :foo/col-name
into java.jdbc
.
@seancorfield: That’s very cool. I suspect work will need to be done on all ends of the stack to make namespaced keys more tenable for the average project.
Now I look at it, I probably won’t need to do anything for pushing namespaced columns into java.jdbc
:
user=> (def db-spec {:dbname "mydb" :dbtype "mysql" :user "tester" :password "secret"})
#’user/db-spec
user=> (j/query db-spec ["select * from status"])
({:id 1, :name "approved"} {:id 2, :name "new"} {:id 3, :name "rejected"})
user=> (j/query db-spec ["select * from status"] {:qualifier "status"})
({:status/id 1, :status/name "approved"} {:status/id 2, :status/name "new"} {:status/id 3, :status/name "rejected"})
user=> (j/insert! db-spec :status {:status/name "test"})
({:generated_key 13})
user=> (j/query db-spec ["select * from status"] {:qualifier "status"})
({:status/id 1, :status/name "approved"} {:status/id 2, :status/name "new"} {:status/id 3, :status/name "rejected"} {:status/id 13, :status/name "test"})
And due to a very recent change, even this works as expected:
user=> (j/insert! db-spec :status {:status/name "qualifier"} {:qualifier "result"})
({:result/generated_key 14})
@jannis: check-var (very soon to be just “test” in the next alpha) is not going to work with macros
@kendall.buchanan: we are considering adding something in s/keys that lets you alias unaliased keys to arbitrary specs, but no guarantees
@alexmiller: Will there be an equivalent for fdef'ed macros?
you can fdef macros now
it’s just that check-var is not going to work to test them, afaik
Is there a way to compose multiple s/key specs into one big one so that a map has to satisfy them all?
@akiel: I wrote a macro that did that because I couldn't find anything. it was kinda painful
@bfabry: I need it to work with multi-spec because I have a big environment map were I have multiple subsets of varing keysets.
I don't know enough about multi-spec to know if it would help, but here it is (very ugly) https://clojurians.slack.com/archives/clojure-spec/p1466110303000387
@akiel you can just do s/and of multiple s/keys
@alexmiller: that won't create good generators though
@alexmiller: Ok I only have to wrap all subsequent s/keys into a one-arg function and ignore the conforming value?
@alexmiller: ok it works
s/and will create a spec, not sure why you need to make it into a function
the resulting conformed value should be the map
I thought there would be always a predicate which gets the previous value. Bit this counts only for preds and not for specs.
not sure I understood that
The example is (s/and even? #(< % 42))
and the doc says: “Successive conformed values propagate through rest of predicates.” So I thought you can have one initial spec and than only predicates which are called with the previous conformed value.
@alexmiller: out of interest is there any move to make some of these macros functions? a dynamic s/keys seems like it could be useful
@akiel: yes, although I think maybe you’re reading too much into the choice of “spec” and “predicate” there
and combines specs which can be either predicates or other things
the conformed value flows through them
@alexmiller Ah ok. I see. The specs get also the previous conformed value and just use it to be able to return the whole thing at the end.
@bfabry: yes, that’s possible. things are macros so that we capture forms for reporting purposes. but there may still be function forms as well (which would fill in under the macro forms)
I have a multi-spec. My in data can look like: {:method :search :search-term "blah" :auth "abc123" :gps-lat 3.4 :gps-long 5.3}
or {:method :get-products :product-id 12345 :auth "abc123" :gps-lat 3.4 :gps-long 5.3}
. My multi-spec already keys off the :method
key. My data has some shared keys: :auth
, :gps-lat
, :gps-long
and some keys that are not shared: :search-term
and :product-id
. Ideally I'd like to create a spec that merges two s/keys
specs into a single s/keys
spec, however s/cat
creates a spec that expects two hashes in a list as opposed to a single hash with merged keys.
I talked through some options for something like this with @luke - maybe he could elaborate on where he ended up
iirc, he ended up with a spec for the common keys and separate specs for each variant
and then specs for each variant that anded common and separate
and then instead of multi-spec, it’s an s/or of the concrete variants
with the downside that it’s a closed system
with multi-spec, you’d have to repeat the keys in each variant
@alexmiller: okay, i'll look into what it looks like with s/or
option and compare that to repeating in a multi-spec scenario. Thanks.
no it would
common = (s/keys …) A = (s/and common (s/keys A…)) B = (s/and common (s/keys B…)) all = (s/or :a A :b B)
that doesn’t help you with the conforming question though
@alexmiller: k i'll give that a try.
@fenton @alexmiller I ran into this too, it seems a common scenario with Datomic "polymorphism" aka {:payment/amount 42, :payment/type :payment.type/stripe, :payment.stripe/payment-id 1234}
- it would be great to have a merge-keys operation that takes two s/keys and merges their implementations - what do you think?
Talked about it with Rich today
We'll see