does anyone have any recs on a test coverage tool for clojure? I'm testing using clojure.test , and looking for a simple breakdown of line and branch covereage a la jacoco.
I have not used it, but Cloverage is one existing tool for that: https://github.com/cloverage/cloverage Not sure off hand if there are any others.
i can already tell I am going to fail to pronounce that 90% of the time
but worth investigating, thanks
We use cloverage at my work, works well enough
@jbaek.in has joined the channel
@stoiczero has joined the channel
Hello. @alexmiller am I right that feature “Maven authenticated repos” (deps.edn) does not support encrypted passwords in ~/.m2/settings.xml? I mean encrypted like this https://maven.apache.org/guides/mini/guide-encryption.html
Honestly, I am not sure, haven’t tried it. We are going through Maven apis to get that stuff, so it’s possible it would work but something more may be needed
I see. I tried settings.xml with encrypted passwords. No luck. It began to work only when I replaced encrypted password with real one.
Thank you for reply
that's good to know, would not be opposed to adding support, but haven't looked at what that would entail
Thank you for deps.edn. I just started learning Clojure but I like that I have out from the box tool to resolve dependencies and to build my sandbox projects.
With javac without ant and maven it's more complicated for sure)))
I mean building java projects without ide
working on something to plug that hole right now :)
wow, great news))
well that, and a lot of other similar holes :)
Can someone explain to my why the handler in the .catch expression is not valid?
(defn sign-in [credentials]
(-> (.signIn Auth (clj->js credentials))
(.then (fn [user] {:result :success :user user})) ;;Works fine - as expected
(.catch #({:result :error :error %})))) ;;Invalid?
This code throws an invalid arity exception when the catch expression is called(macroexpand '#({:result :error :error %})) ;; => (fn* [p1__30029#] ({:result :error, :error p1__30029#}))instead of a map literal you can use hash-map function. #(hash-map :result :error :error %)
So I guess it is because a map literal is not a function?
it can be called as a function ({:foo 1} :foo) but map is a function of one or two arguments
in your case it will throw ArityException
Ah ok, thanks
To be clear, map as a function is for looking up values in a map, and not constructing a map.
(let [f #({:a 1 :b 2} %)]
[(f :a) (f :b) (:f "random")])
;; => [1 2 nil]For anyone who uses timbre, is there any way to blacklist a value? Or I have to use :middleware ?
@postmaster has joined the channel
So I'm trying to create some constants for a noughts and crosses game. In Common Lisp I'd use defparameter for something like that and put asterisks around the symbol. Clojure is complaining and saying I need to mark them ^:dynamic
(def my-constant 1234.123)
Or possibly (defonce my-constant (some-function))
aha the latter looks like what I need. Thanks 🙂
If there's something asking you to mark them as dynamic, that's probably a linting tool? I saw you mention asterisks in another message.
Using asterisks such as *ns* (or, earmuffs as I and a few others like to call them) denotes that this var will be bound by yourself or something else above you. *ns* is ^:dynamic and bound for you. This is just a convention though.
Anything telling you to do that is probably just linting, you should only be adding *...* if you plan to rebind that value in some way with something like https://clojuredocs.org/clojure.core/binding
When I want a constant I'll use def, if it's something stateful like the result of starting a server I use defonce, the main difference is removing the *...* will get rid of that warning.
You use defonce for stateful things so that reloading the file won't overwrite your stateful value.
Got it, thanks 🙂
I'm using Prelude / Emacs, so linting sounds likely
If I had to guess, it'll be clj-kondo or joker integration. And if you don't have those I'd highly recommend looking into them. They can catch all sorts of common mistakes.
heh, that just sent me down the Flycheck rabbit hole, thanks for the tip. They look useful.
First I'm going to try to figure out atoms enough to get the game state functions working properly
But I'll definitely come back to that
this is not a linting feature https://github.com/clojure/clojure/blob/f9b04ae5f7fd9f11ea7a431675f4ec2d23f295f5/src/jvm/clojure/lang/Compiler.java#L567-L569 it comes from clojure compiler
Ta
So the sort of thing you'd use defonce for might be reading a bunch of initial game data from a file?
Mmm, not quite unless I'm misunderstanding. I'd put my game state in an atom held by a defonce: (defonce state (atom initial-state))
This allows you to evaluate the entire buffer with your editor and not worry about resetting the world state. Allowing you to change functions etc without worrying about accidentally resetting the game state. Useful if you're tweaking a render function for a specific state of the game.
Of course you can just evaluate the form you care about and just avoid reevaluating your stateful stuff but sometimes signalling "this thing should persist even as you reload things" helps out other devs too.
You could then have a function called reset-game or something that called (reset! state initial-state) if you wanted to start from the beginning.
Oh OK, that's very useful (although not for the very simple game I'm basically porting from Lisp)
But I'm going to try hangman or something after getting noughts and crosses to work
Actually though, I can use that here too
yes, thanks !
I hadn't got that far (still doing the game loop) but I'll definitely want to be able to initialise and reset state
I was initialising in the repl, but it's better to do it that way
What's the idiomatic way to do something like this? I just want some simple numerical constants and won't be changing them.
def it's ok
values are immutable, so def is OK
Yep ta. I think it was just following Lisp convention and using * in the name that was causing issues
and I can kinda understand it, because Clojure (I think) wants to reserve that for when you really do mean dynamic
@andre.tgmello has joined the channel
@luk.trojanowski has joined the channel
@aman.shah5673 has joined the channel
@frozenfire1992 has joined the channel
I am using reagent and cljs-ajax. I want to make multiple GET requests and store the results in an r/atom. My handler for the get request boils down to
(swap! my-atom into)
so I have this get request wrapped in a function load-url that takes a URL as parameters, and to fill up my atom I do
(defn refetch []
(reset! my-atom nil)
(map load-url '(list of urls)))
When I call refetch in a figwheel repl, it works perfectly. But if I have a button like
(defn refetch-button
[:button
{:on-click (fn [] (refetch))}
"refetch"])
When I click the button, the atom is reset to nil, but it stays nil and it seems like the get requests are not happening. Can anyone help? I've been pulling my hair out over this for a while.its the most common clojure error
@andrea_fleckenstein it will work in the repl but not in your app
map is LAZY 🙂
meaning it won’t execute until its consumed
use doseq
@bhauman what does "consumed" mean?
or you can cheat with mapv
There is also run!
@andrea_fleckenstein consumed means you have to use the map
the results of the map before they are realized
its an amazing feature, but takes some getting used to
it means you can do this (map inc (range))
which will go forever
but you can just take part of it
oh and don’t type that in the repl
@bhauman thank you
@andrea_fleckenstein type this in the repl (take 3 (map #(do (prn "hey") (inc %)) (range)))
you will see that hey is only printed three times
your welcome 🙂
that was not very intuitive, but at least now I won't make this mistake again..... hopefully
@bhauman so it gets consumed in the repl because it is printed?
yep 🙂
is there a good blog post on why lazyness is a super power in clojure?
This one looks OK https://hackernoon.com/clojure-lessons-from-laziness-252ca7fc4fa7
@eduardo196 has joined the channel
ahoy! I started learning Clojure today; sorry if this is too basic a question, let me know 🙂 I ran into some surprising keyword behaviour and I haven't been able to explain it: scratch.core=> (:a :b) nil scratch.core=> (:a :b :c) :c scratch.core=> (:a :b :c :d) Execution error (IllegalArgumentException) at scratch.core/eval1783 (form-init1964860978058534137.clj:1). Wrong number of args passed to keyword: :a
user=> (get :b :a)
nil
user=> (get :b :a :c)
:c
user=> (get :b :a :c :d)
Execution error (ArityException) at user/eval5 (REPL:1).
Wrong number of args (4) passed to: clojure.core/get
user=>
it mirrors the get function
aaah -- that explains it, thanks @hiredman. (doc get) shows that the third parameter is what is returned in the not-found case, which makes sense.
is there any way I could have seen in the repl what was happening behind the scenes?
in my amateurishness, I ran (doc :a) expecting to see the "traits" of a keyword when used as a function.
but that didn't work.
No, unfortunately for that you'd needed to refer to the docs
thanks all!
Reading through https://clojure.org/reference/reader might feel a bit thick at first, but I still recommend it
on it, cheers for the tip 😄
Even if you don't understand it all, later as you learn more, things will click and you'll know where to go looking back and re-read the reference and suddenly it'll make sense
Could someone explain a little further what I am supposed to do with these installation instructions? https://github.com/cloverage/cloverage#installation
It isn't clear to me where this dependency addition is supposed to happen. I don't have a .lein/profiles.clj. Is this supposed to be added directly to the :profiles section of my project.clj?
are you using lein?
I am, yes
adding the dependency directly to your :profiles section of your project.clj should work too
oh wait. adding it to the :plugins* section
.lein/profiles.clj is just if you want to be able to use cloverage from any clojure project without having to explicitly add it for every project
@jason5lee has joined the channel
seems lein profiles plugins are deprecated, and the :user profile should be used instead
ex {:profiles {:user {:plugins [[blah]]}}}
profiles.clj is one big profiles section right?
but for cloverage, I would expect to add the plugin to a project, not my global config
right, that's what I'd prefer as well
and there are a few good reasons to avoid global customization with lein
there are two members connected to this chat with the name "Nicole Kathrine", and at least of them seems to be spammer, if either of you is not a spammer the spammer my be trying to pretend to be you to avoid getting booted