This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-19
Channels
- # adventofcode (44)
- # announcements (2)
- # aws (9)
- # beginners (166)
- # braveandtrue (16)
- # calva (170)
- # cider (14)
- # cljdoc (9)
- # cljs-dev (4)
- # cljsrn (1)
- # clojars (1)
- # clojure (150)
- # clojure-dev (15)
- # clojure-europe (4)
- # clojure-india (3)
- # clojure-italy (93)
- # clojure-nl (18)
- # clojure-serbia (1)
- # clojure-spec (5)
- # clojure-uk (45)
- # clojurescript (54)
- # cursive (19)
- # data-science (8)
- # datomic (83)
- # emacs (6)
- # events (1)
- # hoplon (3)
- # hyperfiddle (3)
- # jobs (6)
- # jobs-discuss (1)
- # klipse (1)
- # lein-figwheel (6)
- # leiningen (15)
- # lumo (1)
- # nrepl (1)
- # pedestal (15)
- # re-frame (48)
- # reagent (4)
- # reitit (2)
- # remote-jobs (1)
- # rum (2)
- # shadow-cljs (111)
- # spacemacs (10)
- # sql (16)
- # testing (10)
- # tools-deps (5)
What’s the recommended way to validate input in a macro? Say I expect a map with one key-value pair. Do I use conditionals and throw an error or is there a better way?
One option is to write a spec with fdef - those will be automatically checked
Another is to manually validate the input and throw an IllegalArgumentException or other similar one - there are a just a few treated like this by the new exception stuff
Thanks a ton. I was looking at the implementation of https://github.com/clojure/clojure/blob/clojure-1.9.0/src/clj/clojure/core.clj#L4590 for reference. Is there any guidance on when you should consider spec vs manual validation?
Both fdef
(on a macro) and that validation code in for
are checked at macroexpansion time and not at runtime.
Can you implement a function iterate*
of your own version, not using clojure.lang.Iterate/create
?
Yes, and it used to be implemented this way before Clojure 1.7
https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L2719
how to invoke method .whereEqualTo in class Query which is already extended in here (com.google.cloud.firestore CollectionReference)
I would check the java docs for whatever you are doing, my guess is whereEqualTo is a java varargs methods, which would mean you need to put the varargs in to an array
actually it looks like that error is coming from inside the google firestore code, likely because of a depedency versioning conflict
Can anyone guide me to some example of how to use prepl? Google is not much help and the API documentation refers to parameters, I do not know how to configure, so some working example would be very helpful. I am not going to use it for anything special, yet, just experimentation.
I’m going to write something up soon, just haven’t gotten to it
Can anyone recommend a good current (2017 or newer) book or detailed guide on web development with Clojure? Since there's no Rails or Phoenix for Clojure, it's hard to know which tools and libraries are ideal for general webdev.
(or is my old 2014 Web Development With Clojure book still relevant?)
A second edition of that book came out in 2016. If I remember them correctly, the 2nd edition has a lot more about the Luminous framework and Clojurescript. From the 1st edition, the ring/compojure/liberator bit is still relevant. The lib-noir library it mentions might be ancient history.
I don't have any recommendations, but given what I've found when reading about this stuff, I'd say that the fundamentals haven't changed a lot (Clojure hasn't changed much since 2014), only the popular frameworks
I guess my concern is that since I'll be learning a lot of new things, I don't want to invest energy on a component that's going out of style. Just hoping to find a set of tools that will last a couple/few years
Reagent seems to be the current de jour react framework (with reframe supporting), and fulcro seems to be the other big name in frameworks

ok, thanks. I'll start looking there
If you want to try fulcro, this is the spot to give it a go: http://book.fulcrologic.com/
Oh super, thank you
@michael_teter there's also http://www.luminusweb.net/ , a "web framework" which is more like an opinionated set of libraries making up a proper web service
Yeah, these days I use luminus + re-frame to set up a basic web app shell and go from there.
i would initially leave out re-frame, it's a world in itself that might distract, depending on what you want to achieve
Ok, if Luminus is popular/relevant, and its website promotes the book I already own, then perhaps I'll just start with the book despite its age 🙂
I don't need front end so much right now, so if I understand correctly that's where re-frame would be involved
Right, re-frame is front-end.
Thanks all.
@michael_teter It depends what you need. If you want to create a web site, I’d go to Luminus. If you want to go for an API service I’d got for https://github.com/duct-framework/duct
Thanks @lukas.rychtecky . I'm not doing an API, at least not at the moment. But I'll put duct in my save-list 🙂
how do people generally new up maps for tests
so if i have a function that accepts a map as a parameter and accesses various keys
and i want to then feed in values from a test
i’m just manually creating the maps in the tests at the moment
but there’s no code completion so i end up flipping between the two files manually generating the map
feels a bit clunky
i was going to have a go at clojure spec to generate some values
i’m used to a typed language, java kotlin etc
when as i’m creating it, intellij suggests parameters for me
@christopher.paul in my deftest
body I generally let-bind the arguments to the function I'm testing.
i mean that if i have a function that accepts a map
its hard to then create the map for the test
but maybe i shouldn’t be passing maps into functions
i’ve posted some data to an endpoint as json
i’m then doin g alittle manipulating and sending it somwhere else
so i want to test the manipulation is right, at the moment maps are being passed around
yea that’s what i’m leaning towards
https://clojure.github.io/spec.alpha/clojure.spec.test.alpha-api.html#clojure.spec.test.alpha/check
It can gen args based on a fn spec and validate that your constraints hold for all n
invocations
W.r.t passing maps into functions, I've found that to be the best approach for having maintainable code, and the openness of clojure maps makes them great for extensibility.
so if i have a function that accepts a map
and returns another
i’m trying to find the best way to assert that the mapping has been done correctly
in java tdd i’d create an input object and verify an output object
not sure whta the equivalent is in the lisp world
I'm not doing generative testing, so in my (deftest test-foo...
form I have a let
binding that defines my input and I have test assertions that the output of the function matches whatever shape I wanted.
yea that’s what i’ve been doing so far
but feel like i’m missing a trick
where spec would help me by generating all of the input data and validating the output shape, I'm doing that by hand.
i probably need to get underneath spec
spec examples all have ::keys
does that mean that the map also needs to have ::key?
(def person {:firstname “chris”})
does that mean i can only use spec if the keys are :: ?
you can use qualified or unqualified keywords, that's what the *-un
keys are for in s/keys
specs
(s/keys :req-un [::firstname])
would work for unqualified :firstname
keys in maps, but ::firstname
refers to a spec for the key's value
I believe what you're after is the :fn
argument to fdef
. It's the "glue" between input and output, it relates them via predicates.
:fn A spec of the relationship between args and ret - the
value passed is {:args conformed-args :ret conformed-ret} and is
expected to contain predicates that relate those values
https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/fdefSo if you had a person
namespace, and in it you did (def person {::firstname "chris"})
that would expand into {:person/firstname "chris"}
>does that mean i can only use spec if the keys are :: ? No, spec can verify unqualified keywords as well
i guess i need to just read up on spec
i sort of see how it can generate input and validate output
but it seems like it will validate the shape but not the contents
that will require a map that has :firstname
key and check its value against ::firstname
spec
but maybe that’s all it’s meant to do
Based on the way I've heard spec talked about, I believe it was designed to allow validating contents.
so if the thing it returns has a list property that is ok to be empty
it might not be ok for itto be empty based on the input it was given
That seems to be Rich's thing about spec vs statically typed languages: statically typed languages can't tell you about the content in a rich way, only in a vague shape way.
sorry i need to read mor about spec, thanks for your help
I'd start with the spec guide: https://clojure.org/guides/spec And then you can take a look at test.check: https://github.com/clojure/test.check There are some good generative testing examples in there.
Generative testing works really well when the input and output are related by some invariant. Sorting for example, the output better be monotonically increasing/decreasing, or we've violated the invariant. Or e.g. a full-name
function: the output better contain both first and last name somewhere in the output string. Functions that are map -> map
might be more difficult to test via invariants due to their high degree of dimensionality; it really depends on what the function is doing...trying to test it generatively may illuminate design flaws, however, and help you decomplect things.
yea map to map is what i’m getting at
its easy to verify the shapes of inputs and outputs, but probablly better the examine the results in specific tests
otherwise it feels like the spec would get really complex
(deftest my-macro-invalid-bindings-test
(testing "my-macro throws error with invalid bindings"
(is (thrown? IllegalArgumentException
(my-macro [] {})))
(is (thrown? IllegalArgumentException
(my-macro [x] {x x})))))
I’m trying to write a unit test to make sure invalid input sent to my macros throws an IllegalArgumentException. However, they are raising errors when the test file is run. What is the recommended way to test a macro?@jayzawrotny That's on 1.10? Macro-expanding errors are wrapped in CompilerException
in order to add all the location/phase data etc.
It would be nice if thrown?
checked both the main exception and the cause. I'll add that to the clojure.test
design wiki page that just got created.
this was the subject of the discussion on clojure ml yesterday
still deciding what, if anything, to do about it
I added a note to the clojure.test page about it. I'll link to that issue.
I have created variant assert-exprs to thrown? to look at cause in some cases. Checking both seems weird to me, but I guess is a viable alternative
Is it this one? http://clojuredocs.org/clojure.test/assert-expr
it’s best to look at the current impls of thrown? etc and do something similar
https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L504-L516
Is there any discussion of the performance impact of tap>
when there's no active taps?
seems no problem? the tap loop isn't started up in the former case and it will remain blocked if the tapq
is empty?
(defonce ^:private tap-loop
(delay
(doto (Thread.
#(let [t (.take tapq)
the take there will just patiently wait i believeCool, I've just been wondering about the viability of using tap>
in production to get on-demand monitoring of data pipelines and such
And the documentation isn't really clear about whether this is primarily targeted towards dev-time use cases or not
I think tap> will always cost one add+take from an java.util.concurrent.ArrayBlockingQueue, even with no active taps
It's a non-blocking queue, isn't it?
From the docs "Will not block."
ah yes. the values will go into that queue. i confused the tapq for values and the tapset for taps
Thanks
Created a solution for
(is (thrown? (eval `(my-macro [] {}))))
Could I get a code review please? Is this something worth putting into a library?
(is (thrown-in-macro? IllegalArgumentException `(my-macro [] {})))
If you use Throwable->map
instead of datafy
, it'll run on Clojure 1.9 I believe? (when was that introduced)
Also that function is not searchable from http://clojuredocs.org and can not be added to see also of related functions. Should I file a bug with clojuredocs?
Worth a try. I don't know how up to date it is supposed to be. I normally go to the API reference docs since they're auto generated and always up to date.
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/Throwable-%3Emap
Thanks. The page does exist, https://clojuredocs.org/clojure.core/Throwable-%3Emap, it’s just odd how hidden it is