This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-19
Channels
- # announcements (37)
- # aws (6)
- # babashka (12)
- # babashka-sci-dev (16)
- # beginners (83)
- # biff (10)
- # cider (14)
- # cljdoc (26)
- # cljs-dev (20)
- # clojure (123)
- # clojure-czech (9)
- # clojure-europe (26)
- # clojure-nl (4)
- # clojure-norway (20)
- # clojure-spec (7)
- # clojure-uk (6)
- # clojured (14)
- # clojurescript (28)
- # cursive (5)
- # datalevin (8)
- # datomic (3)
- # duct (6)
- # emacs (26)
- # events (2)
- # fulcro (7)
- # gratitude (1)
- # holy-lambda (19)
- # integrant (1)
- # jobs (2)
- # leiningen (8)
- # lsp (7)
- # nyc (1)
- # pathom (70)
- # re-frame (8)
- # reagent (15)
- # releases (1)
- # sci (8)
- # shadow-cljs (117)
- # testing (5)
- # tools-deps (11)
- # vim (5)
AFAIK that variant is only applicable to Promises and Futures (that block if not delivered/realised) but I use it quite a lot on Promises in testing async functions to prevent tests blocking forever.
You're right. It's only useful when there is a blocking operation involved. Atoms and Agents are not blocking access to a state. I just didn't know about this arity to exist until I was reading clojure source code. That's why reading (other people) code matters 🙂
Is it this? https://www.ros.org
Hi, I want to add a middleware to reitit that will count the number of requests currently in the server (increment when a request comes in and dec when it ends), how do I do that? planning to use metrics-clojure
I tried adding some middleware like this:
{:name ::format-request
:spec ::spec
:compile (fn [ctx ctx2]
(log/log-map :error nil nil "str" {:ctx ctx :ctx2 ctx2})
{:wrap (fn [x] (println (str "str" {:ctx3 x})) x)})}
but it does nothing sadly, at least the server works but no prints when requests are sentsure, how do I do that? using jetty
If you look at the executor service constructor, you can pass it a queue. Wrap it and inc counters for add and remove
I don’t know, but I will check, thx!
is putting a gauge on the default threadpool ok in your opinion?
(.getIdleThreads (.getThreadPool server))
(.getThreads (.getThreadPool server))
Why not have two counters, for takes and puts? That encompasses all the information you need, no?
decided to go with both. got a gauge and a counter (dec and inc). the gauge feels more “right” cause I don’t need to wrap stuff. the counter feels more “right” since it is always “right” and you don’t have to call some function to fetch it. will see what I decide 😄
Counters are simpler. Also, when you have two, you can compare your ingress rate and your processing rate
I have timers there too, should do the trick, right?
Too much 😄 If you have a counter, the derivative gives you rate I don't see why you need anything besides two counters
went with both for now, will update how it goes 🙂
In my Python projects, I use https://github.com/theskumar/python-dotenv to load environment variables from a .env
file in my project root directory, which I add to my .gitignore
. The library ensures that I don’t commit any secrets (API keys, etc.) to my Git repo and that environment variables are correctly loaded. What would be an idiomatic way of doing the same thing in a Clojure project? How do you manage your secrets and load them as environment variables?
@U031X1BLY5U, How would you load the variables from EDN into the environment/REPL? I thought there might be some de facto standard Clojure library that takes care of that.
you can keep doing the same and read secrets from environment variables.
(System/getenv "VAR_NAME")
jsonista could read it for you
that also mean you have to prepare your environment in production. eg. load .env file before running uberjar
My favorite way of dealing with configuration until now has been juxt/aero, which gives you edn with some useful reader tags, such as environment variables, string interpolation and profiles. You can also include local files
That way you can have a local file with private settings and a production file as part of a repository
You can take a look at this implementation https://github.com/spapas/ringu/tree/master/src/ringu/conf
There are some libraries that do something similar. But as others have said, I think using configuration is better as well. Simply put, don't use environment variables, instead have a config file with secrets in them, could be EDN, and load that. Then when you deploy, you push a similar config file onto your machine where the file only has permissions to be read by the user that is running your application.
Or, if you prefer using environment variables, even though I think it's less secure, you can have a .env file in edn format and write yourself something simple like:
(defn get-env
[k]
(or (System/getenv k) (get (edn/read-string (slurp ".env")) k))
That will get you the environment variable if one exists, or otherwise the key from the edn map from your .env file.
Generally this is all a library like dotenv does, except it uses a weird property-file like format for the .env file.
If you want that as well I found
https://github.com/LynxEyes/dotenv.clj
That does exactly what you want.Thanks for all your advice! I'll probably go for the EDN config file approach instead of environment variables. But I'll check out those other ideas and links as well.
@U01PE7630AC I bumped into this while working through some compojure tutorials: https://github.com/weavejester/environ
I think someone already mentioned juxt/aero, but I think they have it pretty well figured out for managing config and secrets
https://github.com/yogthos/config has been dealing with my env variables for quite some time.
Is there a better way to write this? I want to check if the values of a vector is also contained in a specified set. If they are not, i want to throw an error.
(def allowed-tags #{:test1 :test2 :test3})
(defn ensure-correct-tagging [tags]
(when (some false? (map #(contains? allowed-tags %) tags))
(throw (Exception. "Specified tags are not allowed"))))
This works, but i was wondering if using some
is even necessary. Is there a smarter way?First, it's idiomatic to use a set as a predicate: instead of (map #(contains? allowed-tags %) tags)
, you can instead write (map allowed-tags tags)
.
I'm still new, so if this not idiomatic or correct please correct me. But instead of the some
and map
construction, you could just do a subset check:
(subset? tags allowed-tags)
This seems to work with tags
being a vector also
Edit: subset?
is available through the clojure.set
libraryUsing allowed-tags
as a function will return the tag in question or nil, if not found in the set.
I'd consider something like the following pretty idiomatic:
(when (seq (remove allowed-tags tags))
(throw (Exception. "Specified tags are not allowed")))
This makes use of (seq ...)
returning a nil if given an empty collection.Any reason to prefer that over my subset
solution? 🙂 I personally think that more clearly states intent
clojure.set/subset?
does convey the intention very well! I think the only drawback is that one really ought to use the function with sets, not collections of a generic kind.
For instance, subset?
internally calls clojure.core/contains?
which will not perform a linear search:
(contains? [:b :c :d] :d)
=> false
You could do it slightly more readable with doseq (I think):
(defn ensure-correct-tagging [tags]
(doseq [tag tags]
(when-not (some #(= tag %) allowed-tags)
(throw (Exception. "Specified tags are not allowed")))))
@UCYS6T599 Do I understand correctly that this would work properly?
(subset? (set tags) allowed-tags)
@U03BYUDJLJF it assumes that the arguments are sets. It won't work for anything else though, so that would cause all kinds of issues if one of the arguments is not a set. Also (set nil) would always match, that may be a side effect you might not want?
Yeah as pyry explained it's not guaranteed to work unless the inputs are sets indeed. That's why I changed tags
to (set tags)
in my later solution. Good point about the (set nil)
, I didn't think about that
Is there a transducer versions of conj
and cons
? (Adding something at the end or beginning of a collection/iterator/stream. Ofc. under the assumption that conj
only happens when it’s finite.)
I happened to write an append transducer, not too complicated, though I might have an error https://github.com/bsless/fast.csv/blob/master/src/bsless/fast/csv.clj#L96

doesn't really make sense, but cat
is kind of similar
although cat
is concatenating elements of the source, not a specific value
Oh, hmm. I was trying to find a better way for chaining something like this:
(->> ["b" "c" "d"]
;; other steps
(#(conj % "e"))
;; further steps
(#(concat ["a"] % ["f"])))
(the other steps are easily transduceable, only the concat and and conj parts don’t seem to have idomatic solutions in my current knowledge.)I mean, I guess could make prepend and append transducer functions
I guess this should do the trick
(defn append
"Transducer which continues with a collection of values if completion is reached."
[^Collection coll]
(fn [step]
(let [reduced-preserving-step #(let [ret (step %1 %2)]
(if (reduced? ret)
(reduced ret)
ret))]
(fn
;; init
([] (step))
;; completion
([result] (step (reduce reduced-preserving-step result coll)))
;; perform step
([result input] (step result input))))))
(defn prepend
"Transducer which prepends a collection of values as the leading results until exhausted."
[^Collection coll]
(fn [step]
(let [reduced-preserving-step #(let [ret (step %1 %2)]
(if (reduced? ret)
(reduced ret)
ret))
consumed? (volatile! false)]
(fn
;; init
([] (step))
;; completion
([result] (step result))
;; perform step
([result input]
(if @consumed?
(step result input)
(do
(vreset! consumed? true)
(step (reduce reduced-preserving-step result coll) input))))))))
In this example you are switching between coll operations and seq operations which is why it looks weird to begin with
Generally, I try not to force that into a single chain
Hi ! I have encountered a somewhat surprising behavior and I'd like to make sure I understood it correctly.
(apply and '(true false))
Doesn't work
(apply 'and '(true false))
works. I guess the hint here is that both apply and and are macros so you need to "delay" the application of the macro and
until after apply, thus needing this '
. Should I understand that the macro and
is "expanded" at the same time apply
is, thus leading to my problem ?
Thanks by advance 🙂.(apply 'and '(true false)
doesn’t work how you think. 'and
is a symbol which when invoked as a function will attempt to look itself up in an associate collection. ('and true false)
is “look up ’and in true, and if not found, return the not-found value false”
Macros don’t work on values they work on syntax and forms. Consider this bad example here:
(def x ['foo 1])
(let x (+ foo 3))
the let
macro needs a literal vector of binding symbol and value, not something whose value is a vectorMmmmmm I see your point. So what would be the correct way of doing this ? (reduce and arr)
? (arr being a list)
Didn't know about it but indeed !
Thanks for the help and clarification, much appreciated 🙏