This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-01-06
Channels
- # architecture (8)
- # aws (2)
- # beginners (156)
- # boot (163)
- # cider (22)
- # cljs-dev (2)
- # cljsrn (11)
- # clojars (6)
- # clojure (328)
- # clojure-austin (7)
- # clojure-dusseldorf (10)
- # clojure-italy (2)
- # clojure-russia (19)
- # clojure-spec (178)
- # clojure-uk (86)
- # clojurescript (81)
- # cursive (17)
- # datomic (33)
- # funcool (40)
- # hoplon (8)
- # jobs (5)
- # klipse (13)
- # leiningen (1)
- # luminus (21)
- # off-topic (140)
- # om (49)
- # om-next (4)
- # onyx (29)
- # planck (5)
- # protorepl (2)
- # re-frame (58)
- # reagent (2)
- # remote-jobs (4)
- # ring-swagger (16)
- # testing (1)
- # untangled (26)
- # yada (27)
Noob question, when using xml zippers, is there a way to create programmatically a root node? Can't seem to find one
I tried: (data-xml/element :root {} (map zip/node (dzx/xml-> family-loc :resource)))
but no luck
(xml-zip root)
Returns a zipper for xml elements (as from xml/parse),
given a root element
no I mean, I have already the bits and pieces from the zippers, I want to combine stuff together, but I need a root
yep I am trying now -> (zip/make-node family-loc (dx/element :root {} {}) (dzx/xml-> family-loc :resource))
the above makes it almost right, if only there was only one contect vector and not a vec of vec
aaaand....the winner is: (zip/make-node family-loc (dx/element :root) (map zip/node (dzx/xml-> family-loc :resource)))
why doesn't this work:
(let [func #(println "raboof")
jb (defrecord Foo []
org.quartz.Job
(execute [_ _] (func)))]
... ;stuff
)
=> CompilerException java.lang.RuntimeException: Unable to resolve symbol: func in this context, compiling:(/tmp/form-init7561963032470631764.clj:4:29)
why do I see here
(s/with-gen get-objectNumbers
(fn [] (gen/sample (gen '/string-from-regex #"[A-Z]{2}-[A-Z]-\d{1,4}"))))
@vandr0iy maybe because defrecord generate class and must be compiled before func appears. you can try reify instead of defrecord
@delaguardo unfortunately, that's not an option - quartz, in order to schedule a task, must define a class that implements the org.quartz.Job
interface with the stuff to do to be placed in the execute
method; then, whenever it wants to schedule that job it extends that class... friggin Java """""design patterns"""""
I have this spec : (s/def ::objectNumber (s/and string? #(re-matches #"[A-Z]{2}-[A-Z]-\d{1,4}" %)))
and this generator :
(s/with-gen ::objectNumber
(fn [] (gen/sample (gen'/string-from-regex #"[A-Z]{2}-[A-Z]-\d{1,4}"))))
which produces this output :
[clojure.spec$and_spec_impl$reify__13956
17955548
"clojure.spec$and_spec_impl$reify__13956@111fadc"]
I see this output : ExceptionInfo Couldn't satisfy such-that predicate after 100 tries
@roelofw the generator is randomly producing strings and then checking that they conform to your spec. Given enough time it would generate some that do but it gives up after 100 tries. You need to write a custom generator for that spec as it's too specific for the generic one to cope with. Try reading this: http://clojure.org/guides/spec#_custom_generators
BTW scroll up from that heading in the page and you will see an example of a similar exception and an explanation of why it happened.
Haven't used test.chuck so I suggest you read the readme and try some very simple examples first. Might give you a clue. Always start by simplifying the problem and take it step at a time.
seancorfield said I have to use this template :
(s/with-gen my-spec (fn [] the-generator)) `
and the generator schould be (gen/sample (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})"))
I have this
(s/def ::objectNumber2
(s/with-gen ::objectNumber
(fn [] (gen/sample (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})")))))
I'm keeping a registry of processes in an atom. However, you're not supposed to perform side-effects in a swap!
, so this code is no good:
(swap! processes #(if (get % id) % (assoc % id (create-process! id))))
How would I go about doing this correctly?When I do (s/exercise ::objectNumber)
or (s/exercise ::objectNumber2)
I see this message : AssertionError Assert failed: Second arg to such-that must be a generator
so I wonder what is here the name of the generator :
(s/def ::objectNumber2
(s/with-gen ::objectNumber
(fn [] (gen/sample (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})")))))
@roelof I want to start one and only one process (specifically a core.async go-loop) per id
.
@roelof gen/sample
takes a generator and returns some samples generated from it. It does not return a generator. The anonymous fn needs to return a generator.
@roelof "I think I missed this part : #(s/gen
?" No, s/gen
is for getting a generator from a spec. You already have the generator from the call to string-from-regex
.
Thanks for the tip. This is working :
(s/def ::objectNumber
(s/with-gen ::objectNumber
(fn [] (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})"))))
the custom generator should not use sample
(sorry, reading backchat out of order - looks like you’re there)
another problem : when I do (s/explain :artObject/response (get-data-detail-page ( get-artObject ( read-json-data "SK-C-5" )))
@magnars Here's an idea for how you can accomplish what you want: 1. Try to add the process id to processes
with a unique number as value. 2. Outside the swap!
, create the process, if the process id was added. 3. Exchange the random number with the result from create-process!
.
@henriklundahl: thanks, that sounds like it would work. 👍
@roelof: (s/int-in 1900 2018)
@seancorfield how is the show going ? I know this is offtopic
I'm not at my computer. On my phone. Short replies. Show starts in a few hours, 100 miles from home 😸
Alright I’ve got a silly question
Trying to open package manager with M-x
by pressing command + x
(in Emacs)
Taking me to the last character of my buffer but not opening the command window as I would hope
M-x
is option-x
or alt-x
(on Mac). The command-x
key is S-x
in Emacs speak.
Turns out it’s the option
key 😁
@seancorfield thank you sir!
I have made this function
(s/fdef get-objectNumbers
:args (s/cat :response :artObject/response)
:ret (s/coll-of ::objectNumber))
and made this generator :
(s/def ::objectNumber
(s/with-gen ::objectNumber
(fn [] (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})"))))
I get as message : IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword
stest/check
works on "vars (functions) named by symbols" which is why that second call fails — ::objectNumber
is a keyword, not a symbol.
Try
(stest/check `get-objectNumbers)
(backtick, not quote) or (stest/check ‘paintings2.api-get/get-objectNumbers)
as stest/check
requires a fully-qualified symbol name.(don’t forget to keep your GitHub repo up-to-date @roelof so folks can always see your latest code, when you need help)
the first one gives this as answer :
({:clojure.spec.test.check/ret {:num-tests 1000,
:seed 1483727820434,
:result true},
:sym paintings2.api-get/get-objectNumbers,
:spec [clojure.spec$fspec_impl$reify__14282
7640208
"clojure.spec$fspec_impl$reify__14282@749490"]})
the second one gives almost the same :
({:clojure.spec.test.check/ret {:num-tests 1000,
:seed 1483727903786,
:result true},
:sym paintings2.api-get/get-objectNumbers,
:spec [clojure.spec$fspec_impl$reify__14282
7640208
"clojure.spec$fspec_impl$reify__14282@749490"]})
:thumbsup::skin-tone-2: Often easiest to call (stest/summarize-results (stest/check ‘my-ns/my-fn))
to get sane results back. Failures produce very large output otherwise.
For example:
user=> (require '[clojure.spec :as s])
nil
user=> (require '[clojure.spec.test :as stest])
nil
user=> (defn foo [n] (inc n))
#'user/foo
user=> (s/fdef foo :args (s/cat :n int?) :ret int?)
user/foo
user=> (stest/summarize-results (stest/check 'user/foo))
{:sym user/foo}
{:total 1, :check-passed 1}
user=> (defn foo [n] "Boom!")
#'user/foo
user=> (s/fdef foo :args (s/cat :n int?) :ret int?)
user/foo
user=> (stest/summarize-results (stest/check 'user/foo))
{:spec (fspec :args (cat :n int?) :ret int? :fn nil),
:sym user/foo,
:failure
{:clojure.spec/problems
[{:path [:ret], :pred int?, :val "Boom!", :via [], :in []}],
:clojure.spec.test/args (0),
:clojure.spec.test/val "Boom!",
:clojure.spec/failure :check-failed}}
{:total 1, :check-failed 1}
@seancorfield thanks, that produces this : {:check-passed 1, :total 1}
Yes, for small, simple functions, generative testing is pretty quick.
Behind the scenes, it is generating 1,000 pieces of data that conforms to the :args
spec and then calling the function for each piece, and then verifying the :ret
(and :fn
) spec.
(this is part of clojure.test.check
behind the scenes — adapted from Haskell’s QuickCheck — and the real power behind clojure.spec
for testing)
thanks for the explanation. That was one of the things I liked about haskell QuickCheck
Is it normal with proto-repl that it takes multiple minutes to get in a state where I can work on it
I have this file ( https://github.com/rwobben/paintings/blob/master/src/clj/paintings2/api_get.clj ) in my project and if I start up repl it looks like proto-repl is not responding at all
Sounds like you still have some of the “reload” options enabled?
See ProtoREPL > Settings https://www.dropbox.com/s/zzarlw8z1qlhqxx/Screenshot%202017-01-06%2011.46.06.png?dl=0
Whats the recommended way of actually using your function specs. Do you just use instrument? Is there a way to actually check the :fn and :ret portions, or is there something else?
after that I write the rest and use (stest/summarize-results (stest/check namespace/function)) to test if the function does what I expect. Herefore I only use the
:args` and :ret
part because I have very small functions
how would you specify that both arguments are both extend a protocol, and have the same type just using :args
@adamkowalski I hope this makes something clear for you
like if I want to write an append function, that can work with two vectors, lists, sets, or hash maps
but I want them to be the same type
pairs of vecs, etc...
I guess I could put it as a precondition right? just say that they must have the same type
I think you can put that in the fn . but I can be mistaken as I said earlier im also learning specs and spec testing
(s/fdef append
:args (s/cat :a coll? :b coll?)
:fn (fn [{:keys [args ret]}]
(let [{:keys [a b]} args]
(= (type a) (type b) (type ret))))
:ret coll?)
thats what I was thinking
but instrument doesn’t seem to check either fn or ret
@adamkowalski to specify a relationship between args, just s/and
an additional predicate to the :args
spec
like (s/fdef append :args (s/and (s/cat :a coll? :b coll?) (fn [{:keys [a b]}] (= (type a) (type b)))))
if you want to specify a relationship between args and ret, then that needs to be in :fn
putting it in :args
has the benefit of being checked by instrument
oh yeah that makes things a lot easier
thanks for the tip
I have another question however
Could specs potentially replace protocols? Or I mean, can they provide the same functionality that they can provide?
Instead of specifying that something extends a protocol, could you just continually compose specs and accomplish something similar
@alexmiller Are you a atom user ?
why does this throw an exception? (def c (chan 10)) (>!! c 20) (alts!! [(timeout 2000) c])
. Unhandled java.lang.NoSuchMethodError clojure.core.async$do_alts$fn__12286.<init>(Ljava/lang/Object;Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
@rgorrepati I can’t repro that - I get [20 #object[clojure.core.async.impl.channels.ManyToManyChannel 0x2026efb8 “clojure.core.async.impl.channels.ManyToManyChannel@2026efb8”]]
- a value and the channel c
@alexmiller Interesting..
@alexmiller sorry, may be something weird with my nrepl