This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-01
Channels
- # 100-days-of-code (2)
- # announcements (3)
- # beginners (95)
- # bitcoin (1)
- # cider (18)
- # cljdoc (9)
- # cljs-dev (8)
- # clojure (55)
- # clojure-austin (1)
- # clojure-berlin (4)
- # clojure-italy (21)
- # clojure-nl (1)
- # clojure-russia (2)
- # clojure-spec (47)
- # clojure-uk (31)
- # clojurescript (19)
- # component (8)
- # cursive (5)
- # data-science (2)
- # datomic (33)
- # emacs (7)
- # events (1)
- # figwheel (8)
- # fulcro (16)
- # graphql (27)
- # hyperfiddle (5)
- # jobs (1)
- # jobs-discuss (85)
- # keechma (7)
- # luminus (11)
- # mount (6)
- # off-topic (23)
- # onyx (1)
- # re-frame (4)
- # shadow-cljs (29)
- # specter (19)
- # tools-deps (11)
- # uncomplicate (3)
During development, does it makes sense to use fdef
and instrument
for all my functions or sprinkle my functions with assert
and old enable assertions during development?
Perhaps a combination of the two?
I guess the benefit of fdef
is that it can be in a separate namespace; is that recommended?
I think this depends on personal preference and whether you’re writing something intended to run on Clojure 1.8. I tend to put fdef
next to the function definitions, but keep other specs in spec-specific namespaces
Hmm, ok. Thanks
this lib keeps everything separate so it can be used w/pre-1.9 https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc/spec.clj
Assuming pre-1.9 compatibility isn't a concern, do you think having them together is ideal?
You may already know this ,but it’s perfectly fine to put the fdef
definition above the function definition. I find this much more readable than putting it below the function.
Ah, interesting. :)
It seems like that would defeat some of the namespace'd keyword designs of spec though.
@alexmiller hi! We found strange flawing bug for clojure.spec lib in multithreaded environment. We use latest clojure.spec versions ("0.2.176" "0.2.44") for request validation. Every http request we translate to clojure map, then we call (s/valid? spec input-request-map) for input validation. We have 300 000 sample requests (saved in edn file) for testing (constant requests). If we use one thread on JMeter to send request then we always have result true for (s/valid? spec input-request-map) for every 300 000 constant requests. if we use 2 threads or more on JMeter to send requests then sometimes we have false result. If we save false map to a file and then try to validate it (s/valid? spec input-request-map) then we see that it is always true. If we validate twice in multithreaded env (or (s/valid? spec input-request-map) (s/valid? spec input-request-map) ) then it works (but logs tell us that one of s-exps inside or sometimes false). All map is standard clojure maps (immutable). The code (or (s/valid? spec input-request-map) (s/valid? spec input-request-map) ) works for us as workaround but we can't watch on it without crying. It's Clojure, but we met undefined behaviour like in mutable world.
Sounds unexpected to me. :) Instead of using valid?, could you try using s/explain so you’d get a print to the console when it goes wrong? How is JMeter getting the data to send? Is it possible you have two threads reading from the same reader and thus getting something invalid? If you could isolate this down to something reproducible, would be great to have a jira for it.
Any advice?
@djtango If you are using Leiningen, the command lein deps :tree
can be useful. With tools.deps
there is clj -Stree
. Maybe you were already aware of those and looking for something more, though.
"lein pedantic" is something to look into as it will flag the conflicts for you. Boot has a similar feature on its show
task.
I'm not sure if there's an equivalent yet for clj
...
So, I added (clojure.spec.test.alpha/instrument)
to the bottom of my core.cljs
file, however I have a namespace alpha
which defines a symbol (def global (beta/example ...))
. The problem being that core
depends on alpha
which uses beta/example
prior to it being instrumented. Do I have to add the instrument
to every namespace to avoid this?
if you want that call to beta/example
to get instrumented and you want to keep def global
(instead of making it a function or wrapping it in a delay) then yeah I think you'd have to instrument it separately in this case
Makes sense :thumbsup: In this case, it was easy enough to not define the global, though I could see scenarios where that's not really a solution.
Thanks
How do I spec and instrument functions that will be used during initialization?
How would you spec standards based things. Country codes for example: https://en.wikipedia.org/wiki/ISO_3166-1_numeric
This is where I am so far.
(s/def :iso/country-code (s/and s/string? #(= 3 (count %))))
If you can get a big set of valid sample data and convert it into valid EDN, you could try using https://github.com/stathissideris/spec-provider to infer the spec
@jaihindh.reddy in these kinds of cases I enumerate all the possibilities in a set and use that set in the spec.
@taylor ISO charges money for downloads of data. But it is freely available on their website. Scraping that would be awkward to say the least.
I generate from https://github.com/lukes/ISO-3166-Countries-with-Regional-Codes

Ideally I would love to do something like (into #{} (slurp url-for-all-country-codes))
Country codes should be relatively stable. Dont mind manually updating it
Well, manually is fine, but I would plan on doing it every once in a while. The list of countries is actually surprisingly unstable.
Can I spec protocols and multimethods?
I think you're OK with multimethods tho' (I saw a CLJS ticket that indicated s/instrument
was fixed to work with multimethods, so I assume it works in CLJ too).
On that note, when should I use one or the other?
Currently I think protocols should be the default, and multimethod if you think you need the arbitrary dispatch.
@jaihindh.reddy I think this is still a good set of guidelines https://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/