This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-17
Channels
- # announcements (12)
- # babashka (27)
- # beginners (65)
- # biff (7)
- # calva (21)
- # clj-kondo (1)
- # clj-otel (5)
- # clojure (61)
- # clojure-europe (127)
- # clojure-nl (1)
- # clojure-norway (11)
- # clojure-portugal (2)
- # clojure-uk (2)
- # clojurescript (18)
- # cursive (5)
- # data-science (3)
- # datahike (14)
- # datascript (3)
- # datomic (7)
- # deps-new (11)
- # emacs (31)
- # exercism (1)
- # fulcro (1)
- # honeysql (3)
- # hyperfiddle (38)
- # introduce-yourself (4)
- # leiningen (2)
- # malli (20)
- # meander (2)
- # missionary (3)
- # off-topic (4)
- # pathom (3)
- # practicalli (2)
- # reagent (5)
- # releases (1)
- # sci (1)
- # shadow-cljs (9)
- # xtdb (8)
Hello. What is the idiomatic way to use configs in my clojure code. Essentially the value only is needed in one module (so no global state). But how do I provide it there? Using an atom?
You can just use ordinary Clojure map and pass it as an argument where needed.
Or, if you want to separate config from code, you can put that map inside .edn
file and then load it:
(require '[clojure.edn :as edn])
(edn/read-string (slurp "config.edn"))
You need atom
only if something changes over time.
For larger applications you can use DI libraries such as
https://github.com/weavejester/integrant
https://github.com/stuartsierra/component
https://github.com/tolitius/mountbut i can only read the config in -main function and inject somewhere. In my case I have a compojure route, where every call to a route will need to follow a config-settig. So how can i inject that config in a function, that is being called upon a rest-call
ok, now that I write it and think again about it, I think I found an approach, thanks for chatting with me 😄
Good Morning! I stepped away from learning Clojure for almost a year and now I am back. I was looking for an answer and I asked ChatGPT, here is the text:
? │ find first element in array that meets criteria
A │ You can use the clojure.core/find function to find the first element in an array that meets a boolean criteria.
│ Example:
│ (clojure.core/find #(> % 5) [1 2 3 4 5 6 7 8 9 10])
│ This will return the first element in the array that is greater than 5, which is 6.
But, the find
does not work like that, or am I missing something?yeah that is wrong. chatgpt isnt guaranteed to be correct 😛
Wow, OK, I just wanted to have someone who knows more than me confirm. Thank you...
there's only so much that can be fact checked, take things it says with a grain of salt, not as absolute source of truth 😄
I got this from chatgpt ‘(defn find-first-greater-than-5 [vector] (first (filter #(> % 5) vector)))’
@U2T2ZEVPC, would that be the best way of doing it?
I mean is the ChatGPT recommendation the best?
How would you do it?
(some #(when (> % 5) %) [1 2 3 4 5 6 7 8 9 10])
should be better i think
That is interesting ...
Would have never though of using these 2 functions.
Does it matter much performance wise if I use filter
or the some
solution? Because filter
returns a lazy sequence?
And if you want to not create an unnecessary seq just to drop it after the first call, some is better. I’d use filter if I’m using the seq in other places too, not just for the first call.
And looking at the source for some and filter, some is more more succinct...
filter
& first
might be technically less efficient but some
& when
is far less intuitive and this is #beginners.
In other words, filter
& first
is a perfectly fine answer to this question (I'd only maybe suggest some
& when
if this question popped up in #clojure)
I don't understand this behaviour.
Trying to get data from api json ajax/GET.
It works when it's just array of objects:
[{"name":"mario"},{"name":"luigi"}]
But it don't work when this array of objects is under data key.
{"data":[{"name":"mario"},{"name":"luigi"}
Error: Uncaught Error: nth not supported on this type cljs.core/PersistentArrayMap.
As I understand it converts this json to clojurescript code and try run 'data' as function.
example code:
(defn get-tag-list []
(let [handler (fn [[ok response]]
(if ok
(js/console.log "ok")
(js/console.log "error")))]
(ajax/GET "
{:handler handler})))
So how to unpack data from 'data' key?
assuming cljs-ajax, handler
just gets the response, and the fn's arglist is destructuring, so in the case when a response is sequential (e.g. a vector of maps), ok
will be bound to first item and response
will be bound to the second. In the case where response is a map, the destructuring fails because maps aren't sequential (which is why nth
isn't supported on them, and nth
is used to destructure)
...so you could destructure using map destructuring, or not destructure at all and do whatever you need to do with the response, maybe checking whether it's a list or a map if your call might result in either
@UPBB20W20 It is not clear from your example code what is not working. Like, what is "it" in "it works" and "it doesn't work"?
That said, I will hazard a guess based on the question: We do have to adjust our response parsing to whatever the source cares to send along. So (still guessing), where you have (first response)
, try (first (:data response))
-- to handle this source. Hth!
thank you guys that was silly mistake :/
I'm still confused with handler function.
Like passing 'atom app-state' to handler function.
(defonce app-state (atom {:tags []
:music-videos []}))
(get-tag-list app-state)
(defn get-tag-list [app-state]
(ajax/GET "
{:handler #(swap! app-state assoc :tags (:data %))
:response-format :json
:keywords? true}))
In PHP I would just return data from 'get-tag-list' a then save it somewhere.
In my next step I need to make a <ul> <li> list from result of this api call.
Do I have to create another atom and pass it to :handler?
Can I just make a html list right away?
Time is hard. I want to partition-by
some files by what date they were modified on. I got as far as
(require '[java-time.api :as time])
(let [reports (file-seq (io/as-file path-to-reports))]
(time/instant (.lastModified (first reports))))
but I cannot figure out how to turn an instant into just a date.The package info has a pretty good overview, https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/package-summary.html
It looks like you want LocalDate, https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/LocalDate.html#ofInstant(java.time.Instant,java.time.ZoneId)
The java.time is pretty functional on its own. I've never really felt the need to wrap it (not that thers's anything wrong with wrapping).
see I thought so but
(time/local-date (time/instant (.lastModified (first reports))))
yields
Execution error (ExceptionInfo) at java-time.defconversion/call-conversion (defconversion.clj:69). Could not convert [#inst "2023-02-17T17:32:33.509000000-00:00"] to class java.time.LocalDate!
If you look at the second link, converting from an instant to a localdate requires a ZoneId
getting closer
(let [reports (file-seq (io/as-file path-to-reports))]
(.ofInstant (time/instant (.lastModified (first reports))) "CST"))
but that’s not how to hold a zone IDyou probably want (java.time.ZoneId/systemDefault)
(java.time.LocalDate/ofInstant
(java.time.Instant/now)
(java.time.ZoneId/systemDefault))
ofInstant
is a static method of LocalDate
(let [reports (file-seq (io/as-file path-to-reports))
zone-id (java.time.ZoneId/systemDefault)]
(.ofInstant (time/instant (.lastModified (first reports))) zone-id))
yields
No matching method ofInstant found taking 1 args for class java.time.Instant
which would make me think my parentheses are wrong but I really don’t think they are hmmmm
no worries, java interop can be a bit tricky at first
it's java.time.LocalDate/ofInstant
or LocalDate/ofInstant
if you've imported LocalDate
so this
(java.time.LocalDate/ofInstant (time/instant (.lastModified (first reports))) zone-id)
does it, but,yes, there's an optional :import
allowed in your ns
statement
(ns my.ns
(:require ...)
(:import java.time.LocalDate))
so do I have this right: I was trying to use functions defined in the namespace java.time. But to use the static method of the java.time.LocalDate class (class?), it must be imported
One more bit of java interop confusion: This function is fine
(defn creation-date [report]
(LocalDate/ofInstant (time/instant (.lastModified report)) (ZoneId/systemDefault)))
This function is not
(defn creation-date [report]
(-> report .lastModified time/instant #(LocalDate/ofInstant % (ZoneId/systemDefault))))
They’re evidently not equivalent but I’m not sure whyI think the #
is unnecessary
not that the threading version is that much more readable, but I was wondering if it was interop
generally, anonymous functions inside of threading macros usually don't do what you want
> (read-string "#()")
(fn* [] ())
anonymous functions get expanded before macros, so you get weird results
> (clojure.walk/macroexpand-all '(-> foo #()))
(fn* foo [] ())