This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-03
Channels
- # announcements (35)
- # aws (20)
- # babashka (4)
- # beginners (88)
- # cider (9)
- # clara (1)
- # clj-kondo (6)
- # cljsrn (3)
- # clojure (107)
- # clojure-dev (7)
- # clojure-europe (99)
- # clojure-nl (3)
- # clojure-spec (9)
- # clojure-uk (2)
- # clojurescript (28)
- # core-async (53)
- # cursive (11)
- # datascript (1)
- # datomic (2)
- # emacs (20)
- # fulcro (3)
- # graalvm (4)
- # holy-lambda (18)
- # jobs (1)
- # kaocha (7)
- # leiningen (2)
- # lsp (25)
- # luminus (1)
- # membrane-term (52)
- # missionary (8)
- # nextjournal (19)
- # off-topic (16)
- # other-languages (3)
- # podcasts-discuss (2)
- # polylith (23)
- # re-frame (4)
- # reclojure (6)
- # remote-jobs (1)
- # rewrite-clj (36)
- # ring (1)
- # sci (10)
- # shadow-cljs (7)
- # spacemacs (5)
- # sql (20)
- # uncomplicate (1)
- # vscode (3)
- # xtdb (27)
This seems to only work with (setq cider-show-error-buffer 'only-in-repl)
for errors
Is there a way to remove the namespace prefix from all the keys in a map? I’d like to json-stringify a map and send it over the wire w/o the ns
@titanroark If you just call name
on those keys, you'll get strings without the namespace prefix.
There are a few walk
-related functions in the Clojure library that can make that easier if it's a nested map. Or just use org.clojure/data.json
(or Cheshire or jsonista) to turn it into actual JSON, which should all lose the namespace prefix, or can be configured to do so.
I’m actually using your jdbc-next library. I saw up above someone ask a similar question and a response that toggled the namespaces on or off, but I was looking for something more general, thus this question.
When I did (name (:table/uuid_field) map)
it threw an error saying a uuid type can’t be converted to a name
(name (:table/uuid_field) map)
-- that first tries to "call" the keyword :table/uuid_field
with no arguments, hence the error: (:table/uuid_field)
is a function call. (reduce-kv (fn [m k v] (assoc m (name k) v)) {} the-map)
would apply name
to each key in the-map
. In Clojure 1.11 (Alpha 2), you could just say (update-keys the-map name)
data.json
is a nice library because it's "fast enough" for nearly all uses and has absolutely no dependencies. Both Cheshire and jsonista bring in Jackson libraries (Java JSON stuff) that are notorious for causing conflicts with other libraries that also do JSON using (a different version) of Jackson.
Ah yes, I typed the function call out wrong in slack. And that update-keys
fn sounds really nice. Thanks for the reduce-kv tip, the data.json library did the trick well for me, so I won’t need to manually map. And good to know about the library differences, Cheshire starts off with saying its faster so I just went with that
Yeah, it used to be. data.json
has had some major speedups lately. It's not always the fastest - jsonista usually is - but it is certainly fast enough and we switched from Cheshire to data.json
at work for all our production usage recently (to avoid Jackson). I blogged about at http://corfield.org
dev=> (require '[clojure.data.json :as json])
nil
dev=> (json/write-str {:foo/bar 1 :bar/quux "two"})
"{\"bar\":1,\"quux\":\"two\"}"
with the Contrib lib.https://github.com/clojure/data.json for more details.
Hi I have the following reitit endpoint in my server:
["/organizations/:id/users/:uid"
{:put {:summary ""
:parameters {:role string?}
:responses {200 {:body map?}
500 {:body string?}}
:handler foo}}]
And I make the request using http-xhrio in reframe like so:
{:http-xhrio {:method :put
:uri (str "/organizations/" (get user "organization-id") "/users/" (get user "id"))
:params {:role role}
:format (ajax/json-request-format)
:response-format (ajax/json-response-format {:keywords true?})
:on-success [:block-editing/handle-success]
:on-failure [:block-editing/handle-error]}
But I get the following error:
xhrio.js:645 PUT 404 (Not Found)
Any ideas why?1. do you have any prefix in the routes, e.g. ["/api" …]
?
2. does foo return non-nil?
I whipped this up pretty quick, seems to work as expected (https://github.com/dharrigan/simple-reitit/blob/master/src/simple/reitit/main.clj)
@U055NJ5CC I had forgotten “/api” but it still gives the same error:
PUT 400 (Bad Request)
no actually it gives bad request instead of not found
not sure why
It may be worth while to put onto github or summat an example that fails, a fully working example
In core.async is there an opposite to "onto-chan" that returns a collection of the items in a channel? Is there a better alternative?
I am writing out some data into an edn file I can see in the file its tagged like this :created #time/instant "2021-10-23T19:25:46.574852Z",
how ever when I read it back in using slurp and read-string I get this :created (. java.time.Instant parse "2021-10-21T11:54:31.831771Z")
this is causing my code to fail when I call things like tick/year I get an IExtraction error I would have expected the read edn to match the initial tag of #time/instant so bit baffled as to whats happening, any one able to point me in the right direction ?
never mind combination of things using the wrong read-string, and then needing to add my own reader for the tag
How do you pass arguments in double dot notation
((.. fs -promises readFile) "db.edn")
or (.. fs -promises readFile "db.edn")
P.S. - doesn't work with either of them
This worked - (.readFile (.-promises fs) "db.edn")
it works just like ->
, if you're familiar with that macro
The ..
equivalent of the solution you found is
(.. fs
-promises
(readFile "db.edn"))
imho, a matter of preference, although with the get-in
variant, you can have a default value if not found.
you could have that with -> too, if "not found" is at a specific loc (-> m :a (:b :whoops))
:)
i’ve seen a good argument (i think from zach tellman) that you should always prefer to use the functions that most concretely represent the type. I need to go look it up. But i thought it was a useful guideline
get-in is more dynamic, e.g. the list of keys does not need to be a compile time constant
-> is likely going to be faster (constant fixed set of keys, for certain things keyword look up calls turn into field accesses), but maybe not by enough to care about, -> allows for more complicated processes because you can stick random functions in there
-> is I think definitely faster right now (but that may not always be the case in the future)
that is surprising to me. i would have guessed get-in
would be faster, kinda specialized to key value lookup
I mean, -> expands into a fixed set of function calls, get-in is a loop over the contents of a vector
user=> (dotimes [_ 10] (time (dotimes [_ 100000] (-> m :a :b))))
"Elapsed time: 5.769764 msecs"
"Elapsed time: 2.083059 msecs"
"Elapsed time: 2.065704 msecs"
"Elapsed time: 2.026249 msecs"
"Elapsed time: 1.989106 msecs"
"Elapsed time: 1.969671 msecs"
"Elapsed time: 1.446167 msecs"
"Elapsed time: 1.416666 msecs"
"Elapsed time: 1.408738 msecs"
"Elapsed time: 1.409222 msecs"
nil
user=> (dotimes [_ 10] (time (dotimes [_ 100000] (get-in m [:a :b]))))
"Elapsed time: 21.282209 msecs"
"Elapsed time: 15.645264 msecs"
"Elapsed time: 13.058268 msecs"
"Elapsed time: 12.87428 msecs"
"Elapsed time: 7.01354 msecs"
"Elapsed time: 6.806815 msecs"
"Elapsed time: 6.66232 msecs"
"Elapsed time: 6.803173 msecs"
"Elapsed time: 18.48002 msecs"
"Elapsed time: 5.500962 msecs"
nil
easy to test
in opposition to the argument above, I think there is actually an argument to rely on as few assumptions about type as possible
that’s a really good point. I wish i could find where he made that argument so I could see the reasons and if he qualified it in any way
ah thanks @U0NCTKEV8
yes it is guides for keeping the shape of data in the readers head as i remembered it. addressed by other means as well but still a decent idea to me
the counter argument is write the code as generically as possible so you have to care about the exact shape as little as possible
I favor the latter :)
there are plenty of times in Clojure where you can change the implementation between a map or a function, or between a vector or a list or a seq or even a set, without changing the caller. that's an amazing option to have.
lookup is more generic than maps
but as I said, get-in
could be, and should be, faster than it is so don't carry this performance comparison as absolute
I use both ->
and get-in
in these cases and choose primarily on which one is easier to understand in the context of the code

the perf argument is weak, unless you're in a very hot path here (like the page router of your web app)
and even in that case, hotspot in a new jvm might make the above a wash
in fact, that was java 8 above, here's java 17
user=> (dotimes [_ 10] (time (dotimes [_ 100000] (-> m :a :b))))
"Elapsed time: 11.085806 msecs"
"Elapsed time: 5.569733 msecs"
"Elapsed time: 5.167711 msecs"
"Elapsed time: 5.269218 msecs"
"Elapsed time: 5.093628 msecs"
"Elapsed time: 5.052448 msecs"
"Elapsed time: 5.143588 msecs"
"Elapsed time: 2.802478 msecs"
"Elapsed time: 1.395313 msecs"
"Elapsed time: 1.411534 msecs"
nil
user=> (dotimes [_ 10] (time (dotimes [_ 100000] (get-in m [:a :b]))))
"Elapsed time: 21.824148 msecs"
"Elapsed time: 17.589059 msecs"
"Elapsed time: 13.940786 msecs"
"Elapsed time: 13.9655 msecs"
"Elapsed time: 3.989803 msecs"
"Elapsed time: 4.947388 msecs"
"Elapsed time: 4.247937 msecs"
"Elapsed time: 3.350112 msecs"
"Elapsed time: 4.805961 msecs"
"Elapsed time: 6.8933 msecs"
(defn has-keys? [m keys]
(apply = (map count [keys (select-keys m keys)])))
is this a good solution to check if a map have contains all of some given keys?from here https://rrees.me/2012/08/11/clojure-does-a-map-contain-all-the-specified-keys/
(every?
m
the-keys)
I figured out this solves has-keys?
if I'm not mistaken. Well I guess it doesn't handle nil or false values if the use case is to check contain?
but it isn't my case so yeaI'm using the following to check if a map contains all the keys, does it help?
(defn keys-check [m & ks]
(every? #(contains? m %) ks))
;;---------TESTING FNS----------
(deftest keys-check-test
(testing "Basic test cases"
(let [x {:a 1 :b 1 :c 2}
y [{:a 1 :b 1 :c 2}
{:a 1 :b 1 :c 2 :d 5}]]
(is (true? (keys-check x :a)))
(is (true? (keys-check x :a :b)))
(is (true? (keys-check x :a :b :c)))
(is (false? (keys-check x :d)))
(is (false? (keys-check x :a :d)))
(is (false? (keys-check x :a :b :c :d)))
(is (every? true? (map #(keys-check % :a :b :c) y)))
(is (false? (every? true? (map #(keys-check % :a :b :c :d) y))))
(is (every? false? (map #(keys-check % :a :b :c :e) y))))))
Hello friends! I'm trying something here:
I have a project that I'm starting off with clojure and I'll be deploying it on aws batch. This means this is going to be shipper as an docker image. For testing I would like to run tests and, some things, in docker. Also I don't want to miss on Calva.
The tricky part is about environment variables. I configured environ
and I have correctly set up the profiles, so locally, calva works just fine. However, for docker/docker-cmpose I'm using .env
as a way of configuring the environment variables for the image.
Is there a lean way of writing this only once and having access to the best of both worlds? Or should I just open up the REPL server in docker and allow calva to connect to it?
I think this is a common antipattern with clojure and docker. Don't dev inside docker, dev as normal, build an uberjar, package uberjar inside a docket contianer, done
Yea thanks! I'll follow that route for now!
Hi. I've decided to start thoroughly studying the clojure standard library. Thus I'm looking for advice on how to approach it. Which resources did you use/are you using for this purpose? I'm thinking I should just read clojure-docs, source code and usage examples for every core function. Do you think there is a better way? Any resources that are worth noting? I came across "Clojure the essential reference", but wasn't able to find a free copy anywhere, so it's not really an option for me.
I learned it by utility by just googling generic questions like "how do I remove various keys from a map?" whenever I ran into a problem, until I got a hang of the ones I commonly use. also https://clojuredocs.org/clojure.core is your friend.
@U1Z392WMQ Yep, that's what I'm probably going to do.