This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-29
Channels
- # aws (1)
- # beginners (78)
- # boot (27)
- # cider (16)
- # clara (15)
- # cljs-dev (84)
- # cljsjs (13)
- # cljsrn (19)
- # clojure (65)
- # clojure-france (10)
- # clojure-italy (8)
- # clojure-russia (35)
- # clojure-spec (34)
- # clojure-uk (124)
- # clojurescript (50)
- # clojutre (3)
- # core-async (16)
- # data-science (18)
- # datascript (1)
- # datomic (9)
- # emacs (2)
- # flambo (3)
- # fulcro (55)
- # graphql (3)
- # hoplon (4)
- # jobs (2)
- # juxt (21)
- # keechma (6)
- # lumo (73)
- # off-topic (4)
- # om (10)
- # onyx (5)
- # parinfer (1)
- # pedestal (3)
- # re-frame (60)
- # reagent (19)
- # specter (24)
Is there a more idiomatic way to handle this?
(mapcat #(clojure.string/split % #" ") ["I am groot"])
-> ("I" "am" "groot")
I don't want it to output a nested collection. So mapcat
seems the way to go. Any better options?is there some reason that’s not sufficient?
I guess maybe you don’t like having to wrap vector on the input?
(clojure.string/split "I am groot" #" ")
is basically same
I guess if that vector is only ever expected to be of length 1 then (clojure.string/split (first v) #" ")
may be more intention-revealing. but if not what you have makes sense
(into [] (mapcat #(clojure.string/split % #" ")) ["I am groot" "hey there"]) ;; transducer style
not sure what you care about whitespace, but #"\s"
uses Java regex pattern for whitespace, so will catch tabs etc
I think it's just the idea of structuring a nested map using map
and then destructuring it with cat
. But I suppose that has to happen with any implementation really. Probably just overthinking it 😃
it's been a while since I've thought about them but I think the transducer version doesn't have that interim structure
Is there a function that splits a collection into two groups based on bool. e.x. [(filter coll) (remove coll)]
@nbardy: is partition-by
, or group-by
what you want? (vals (group-by pred coll))
should be pretty close.
@srihari (vals (group-by pred coll))
does what I want. Wondering if there was a single function for it.
I'm trying to learn the very basics of clojure now by reading some csv data, parsing it into a map and playing around with transforming it in different ways. What's a good clojurian way to filter a sequence of maps based on the values of a particular key? Data looks like this:
[{:a "" :b "foo"}, {:a "2", :b "bar"}, {:a "3", :b "baz"}]
And I only want to keep the maps where :a is not ""keywords are functions that get the corresponding keys out of maps (:a {:a 2})
returns 2
comp
is for function composition. (comp empty? :a)
is equivalent to (fn [m] (empty? (:a m)))
Now I just have to find the few places where I have an awkward (filter #(not (...)))
and replace it with remove
😉
Thank you guys a ton! I've started using the threading macro and comp seems super duper helpful
So I'm getting this weird error where a specific "namespace is not found." However I have the namespace clearly defined and it works occaisonally (I'm doing this in emacs with cider if that matters). It especially works after I run cider-load-buffer
(at least usually)
I’m sort of confused about how cljs-http
works in terms of Clojure data structures.
I have two functions that are simply making an HTTP GET request, returning the body of the response, and attempting to print the first item in the response collection:
(defn get-http-result [path callback-fn]
(go (let [response (<! (http/get (str js/location.pathname path)))]
(callback-fn (:body response)))))
(defn get-available-commands []
(get-http-result "/commands" #(prn (first %))))
Hmm. I added what you said:
(defn get-http-result [path callback-fn]
(go (let [response (<! (http/get (str js/location.pathname path) {:accept "application/json"}))]
(callback-fn (:body response)))))
I imagine I can reduce over the response and convert it to a vec of maps, but that seems highly unnecessary
So I got it to work, but again, I feel like it’s highly unnecessary lol:
(defn get-available-commands []
(get-http-result "/commands" #(println (first (js->clj (js/JSON.parse %))))))
Never mind, I figured out what I was doing wrong. On the back-end, I was serving the response with a content type of “text/html” rather than “application/json”. Also, I changed my cljs-http using function to:
(defn get-http-result [path callback-fn]
(go (let [{response :body} (<! (http/get (str js/location.pathname path)))]
(callback-fn (vec response)))))
Now the response is a Clojure vector containing Clojure maps.In case anyone else runs into this, this guide is what led me in the right direction: https://zaiste.net/posts/web_applications_in_clojure_all_the_way_with_compojure_and_om/
The issue I’m running into is that (get-http-result "/commands" #(prn (first %)))
seems to only print [
to the console log, rather than the first item in the collection.
I guess should also say that the response body looks like this: [{"section":"System Status","command":"Media Files Uploaded","important":true},{"section":"System Status","command":"Temperature","important":false}]
Are functions like swap!
, alter
and commute
synchronous? I mean, do they block until completion?
they're synchronous, that is, the computation is guaranteed to be terminated when they return
but they don't really block the thread, they retry until the transaction is consistent
@leonoel nice, thanks! Still related to causing side effects: What if I want to do something like a “Java business transaction”? Say that I have to send an email, put a message on a MoM queue and persist to a database. How do I prevent these from being repeated every time the transaction retries? If the answer to this is long, you can give me some terms or key-words for a research
all sends to agents performed during the transaction will be delayed until the transaction is successful, so they will effectively happen just once
Makes sense. The side effect will be caused on the async execution, right? Stretching this just a little bit more: what if the side effect fails? For example, what if the email server fails and the other two servers commit the changes? In Java EE (and in other places too, but I’m really used to Java EE) we have the two-phase commits to address this (not completely, but with an extra layer of certainty). Is there anything similar in Clojure or is this a simple matter of dealing with it manually?
there is no such mechanism out of the box, you will have to handle async errors manually
I’d take a few minutes with the Google - unlike the Java EE world, the Clojure community is very much about composing smaller, specialized libraries to do what you want
I’d bet someone has written a thing to abstract “handle async failures gracefully” and put it on Clojars, is what I’m saying.
I see. Well, that is a very difficult problem, because if you try to be prepared for every possible failure, things will get complicated 😅
@chris_johnson that is beautiful! I’m loving the idea of composing the solutions from small libraries that do one thing right, feels a lot like unix
Welcome to the Clojure community! You’re going to like it here. 😄
@lvbarbosa I think many developers, and perhaps most clojurists, would look to publish a message to a durable topic and have e.g. the email system subscribe to that topic, instead of trying to ensure multi-party transactions resolve all effects synchronously
@donaldball I see, makes more sense!
Never mind, I figured out what I was doing wrong. On the back-end, I was serving the response with a content type of “text/html” rather than “application/json”. Also, I changed my cljs-http using function to:
(defn get-http-result [path callback-fn]
(go (let [{response :body} (<! (http/get (str js/location.pathname path)))]
(callback-fn (vec response)))))
Now the response is a Clojure vector containing Clojure maps.In case anyone else runs into this, this guide is what led me in the right direction: https://zaiste.net/posts/web_applications_in_clojure_all_the_way_with_compojure_and_om/
Let's say I have a vector [a a a a a a a]
where a
is a gigantic map; does the vector contain 7 copies of a
in memory? Or is the value of a
cached and referenced for each (to reduce memory)?
@dadair There will only be one instance of the map; this is one of the benefits of persistent collections. 🙂
in this case I think the fact that java doesn’t have value types would ensure this anyway
thanks, I assumed as much, wanted to confirm before propagating a huge map to a bunch of smaller datastructures as "metadata"
(defn setup-types [userid]
(import-action-template 1 userid)
(import-action-template 2 userid)
(import-action-template 3 userid)
(import-action-template 4 userid))
I have a block like that, and inside the import-action-template, it runs some jdbc inserts using
(map #(write-to-db! %) list-of-maps)
Only the last import actually runs the sql statements. Guessing it's something to do with laziness. Any ideas?or you can replace map with run!
- doall
is for when you still need the return value of map, and dorun
is for when you need an argument arity that run!
doesn’t support but don’t need the return value, and run!
is for when you don’t need the return value and are only providing a function and a single collection as args
I’d love to see an example of dorun
supporting a different arity; I’m not quite getting that.
map supports arities that run! doesn’t
I communicated that poorly