This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-12
Channels
- # announcements (1)
- # aws (1)
- # beginners (182)
- # boot (33)
- # calva (87)
- # cider (3)
- # clj-kondo (2)
- # clojure (108)
- # clojure-dev (73)
- # clojure-europe (2)
- # clojure-italy (27)
- # clojure-nl (22)
- # clojure-norway (1)
- # clojure-spec (1)
- # clojure-uk (122)
- # clojurescript (78)
- # cursive (5)
- # datomic (17)
- # duct (2)
- # emacs (25)
- # events (3)
- # figwheel (1)
- # figwheel-main (1)
- # fulcro (88)
- # kaocha (6)
- # leiningen (2)
- # luminus (1)
- # lumo (4)
- # nrepl (4)
- # off-topic (37)
- # onyx (1)
- # re-frame (35)
- # reagent (1)
- # reitit (4)
- # shadow-cljs (8)
- # spacemacs (22)
- # specter (2)
- # sql (19)
- # tools-deps (12)
- # vim (11)
I was trying to do something with a ridiculously large integer
(bit-shift-right 360027784083079948259017962255826129 1)
and got this
bit operation not supported for: class clojure.lang.BigInt
Is there any workaround, other than just using quot
?
I saw that, but when I tried
(BigInteger/shiftRight 360027784083079948259017962255826129 1)
I got this
No matching method shiftRight found taking 2 args for class java.math.BigInteger
It's an instance method, not a static method.
You have to call it like this (.shiftRight my-big-int 1)
the “object” is the first argument, so always (.methodName obj arg arg arg)
It also works that way with Clojure protocols
I haven’t gotten that far yet 😅 Mostly doing math-y stuff. Haven’t had a need for anything fancy like protocols and polymorphism yet
Is there a smarter way to do the following, given a list of pairs
:
[(apply min (map first pairs)) (apply max (map second pairs))]
? The thing is that this solution iterates pairs twice, which isn't optimal. Though maybe I am just prematurely ptimizing...This is more efficient though hard to read
(->> [[1 2] [10 20]]
(apply map (juxt min max))
((fn [[[mn _] [_ mx]]] [mn mx])))
; => [1 20]
(reduce (fn [m item] (-> m (update-in [:max] max item) (update-in [:min] min)))) {:max Long/MIN_VALUE :min Long/MAX_VALUE} pairs)
thank you but I would expect there must be a simpler way...
If I have a structure such as '((\2 \1))
what function can I use to add \0
to create '((\0 \2 \1))
. Thank you
(map #(conj % \0) '((\2 \1)))
would work. although there’s probably a more elegant solution
Thanks, that's elegant enough 🙂 I tweaked it to concat instead of conj as I realised I was adding (\0)
rather than \0
. All good now
Hi folks! After running lein new app & lein uberjar i get two jars. What’s the difference between snapshot.jar and snapshot-standalone.jar?
@igor246 The standalone jar is a jar with all the dependencies bundled in. The other one is just your code. The standalone one can run anywhere with a JVM but the normal ones needs your dependencies on the classpath
You can see it in the size difference of the two jars
@igor246 snapshot-standalone.jar is the uberjar and includes the clojure library as well as your own application code, so can run without having the Clojure library available in the environment. For the snapshot you also need to include clojure library in the environment for it to run. https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#uberjar
So I have the following snippet of code: https://gist.github.com/victorb/88f8137ab1b87dc0500f066bcce0406b
It reads a stream via http that never ends. On every new item in the stream, it correctly calls the callback and the function itself is non-blocking. So far so good.
However, I want the function to return a function that will close the stream when called. This also works correctly, but it seems that when I'm calling the function, (which in turn calls .close
on the stream) it blocks until another item in the stream appear (but it never calls the callback, which is correct).
What am I missing here? I want the stream to be closed immediately, not when the next item in the stream gets sent
@victorbjelkholm429 I am pretty sure it is the behavior of with-open that is messing things up.
I was thinking the same thing, but now I’m looking at line-seq
hm, I'll give it a try to handle it manually. Thanks @henri.schmidt
Yeah, you’re already handling the close manually, so you shouldn’t need with-open
ok, changed it to the following:
(defn listen-for-changes [callback]
(let [rdr ( (java.net.URL. url))]
(future
(doseq [line (line-seq rdr)]
(callback (:id (json/read-json line true)))))
(fn [] (.close rdr))))
Still, calling the returned function blocks until a new item appears in the streamOk, that’s what I was thinking might happen. line-seq
calls .readline
internally, and I’m guessing that the .close
waits for .readline
to return before actually closing.
(source line-seq)
(defn line-seq
"Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader."
{:added "1.0"
:static true}
[^java.io.BufferedReader rdr]
(when-let [line (.readLine rdr)]
(cons line (lazy-seq (line-seq rdr)))))
You might do better rolling your own interruptable version of line-seq
I see. Thanks a lot for digging in and helping out @manutter51!
Ended up wrapping the .close
in a future
instead, so users of the lib (probably just me) can decide if they want to wait for the stream to properly close or not.
That’ll work 🙂
Now you got me curious about how to write a non-blocking line-seq.
I got stuck at ".readLine is supposed to abort if the stream is closed, but the stream doesn't close because .readLine is trying to read"
I’m thinking maybe something like this:
(defn get-next-line
[^java.io.BufferedReader rdr interval]
(while (not (.ready rdr))
(Thread/sleep interval))
(.readLine rdr))
(defn line-seq-non-blocking
[^java.io.BufferedReader rdr]
(when-let [line (get-next-line rdr 100)]
(cons line (lazy-seq (line-seq-non-blocking rdr)))))
(def counter 1) (doall (for [res getImageId] (do (def setImageID (split-numbers (res :id_image))) ) ;; counter needs to be increased how to inceremet counter ) ) how to set the counter increment in doall
@sagar16jadhav check out map-indexed
for a way to turn a list into a numbered list. Also def
inside a function probably isn’t doing what you want. Think of def
as defining a global constant. You want it at the top level, and you want to def
things only once.
If you just want to count how many imageID’s you have, you can use the built-in function count
.
Hi folks. I’m still a bit of a Clojure noob, and I’m trying to figure out the Clojure way to do a lookup in a hash table…
I have a table like the following:
(def people
[{:name "Anne" :id 1 :sort 1 :system true}
{:name "Barry" :id 2 :sort 1 :system false}
{:name "Chris" :id 3 :sort 1 :system true}])
(defn lookup-people [num] ??????)
(lookup-people 2)
=> "Barry"
Can you please help me with the magic inside the ??????, or point me in the right direction?(defn lookup-people [num]
(->> people
(filter #(= (:id %) num))
(map :name)
(first)))
yes that would be better
(defn lookup-people
[people num]
(->> people
(filter #(= (:id %) num))
(map :name)
(first)))
Thank you both so much!
it works because the key names (`:id` and :name
) are used as the lookup function on the hash map
I’m still trying to wrap my brain around ->>
. Looking it up now…
its very simple, taking first result and passing it as second parameter for next expression, repeats
Ahhh, it’s the reverse of ->
but puts it last…
there's quite a lot of Clojure stuff going on in lookup-people
to be fair
threading macros, transducers, key-as-functions, lambda function shorthand
if i remember correctly clojure core lib takes objects first and collections last hence -> ->>
Nitpick: there’s no transducers here, just a plain map application. It looks like a transducer, E.g. (map :name) but the thread-last macro is rewriting it.
@scotto When I have to do something like that, I usually convert the list into a hash-map.
(defn by-id
[coll]
(reduce (fn [m i]
(let [k (:id i)]
(assoc m k i)))
{}
coll))
=> #'user/by-id
(get (by-id people) 2)
=> {:name "Barry", :id 2, :sort 1, :system false}
If you’re going to be doing a lot of lookups, it’s handy to just convert to hash-map once and keep the result for future lookups.
@scotto you can even provide :id is a key argument in above example (defn by-key [key coll] ...)
Yeah, it's just a shortcut, for convenience.
Yeah, it’s handy.
Fun fact: I recently found out you can do this:
(:foo {:bar 1} :key-not-found)
=> :key-not-found
(:foo {:bar 1} :some-default-value)
=> :some-default-value
I recently did too, but be sure this is what you want when the key is present with a nil value:
user=> (:foo {:foo nil} :key-not-found)
nil
Yep, I’ve been bitten by that one more than once. Caveat coder.
OK, because of @alexmiller I’m looking up into
. At https:http://clojuredocs.org/clojure.core/into the first example shows
; When maps are the input source, they convert into an unordered sequence
; of key-value pairs, encoded as 2-vectors
(into [] {1 2, 3 4})
=> [[1, 2] [3, 4]]
However, I’m getting a “null pointer exception” in my REPL when I try that.(into [] {1, 2} {3, 4})
NullPointerException clojure.core.protocols/iter-reduce (protocols.clj:49)
into
takes 1 source collection
OK, without the comma it works.
commas are whitespace, so that's not the difference
I was trying to mimic the example from the clojuredocs
page.
(into [] {1 2 3 4})
=> [[1 2] [3 4]]
(into [] {1, 2} {3, 4})
NullPointerException clojure.core.protocols/iter-reduce (protocols.clj:49)
ahhhhh, I see. Thanks.
It’s important to transcribe the syntax properly. 😱
lol yes. Sorry
@scotto mistakes are essential part of human existence, look at them as something unavoidable, smile and keep moving forward.
HI curious if it's possible/normal to destructure two hashsets passed into a clojure function? I'm not sure if I have the syntax right. I get an exception when trying it like below:
(def h1 {:x 23 :y 31})
(def h2 {:a 32 :b 44})
(defn h-add
[
[{:keys [x y]}]
[{:keys [a b]}]
]
(+ x y a b )
)
(h-add h1 h2)
I get a `Syntax error (UnsupportedOperationException) compiling at (core.clj:26:1).
nth not supported on this type: PersistentArrayMap`very possible I have the syntax wrong, trying to get a better handle on how destructuring works in closure
(defn h-add
[{:keys [x y]} {:keys [a b]}]
(+ x y a b))
and that is normal and idiomatic
I guess my confusion is around how the :keys
symbol fits with everything else. I'm reading that as a "a hash map with a :keys
element and a vector element containing a
and b
Does :keys
get used in other contexts in clojure other than arg destructuring? How should I read that code in my head?
I know that with a function the first pair of [] is the args, another pair means we've destructured a list or vector (right?), do we use {} when working with hashmaps and sets? thanks!
If that's the case then this suddenly makes total sense, I just had to say it out loud in Slack I suppose
this is a pretty good guide if you haven't read it: https://clojure.org/guides/destructuring#_associative_destructuring
{ }
in destructuring is used for associative data. like maps, records, sorted-maps, and anything that implements the associative protocols
so the {} are notation saying "I'm destructing something associative", and :keys is just something that will get that associative data?
{:keys [a b]}
will pull from {:a 1 :b 2}
the values 1
and 2
and assign them to the local bindings a
and b
fantastic. I could do other things to get the data, but they must be something that gets data via the keys. If I were to do something like h-add (vals h1) (vals h2)
then I would destructure it with [] instead?
Thank you so much @lilactown!
I have re-read the destructuring guide on the Clojure site so many times - eventually it clicks! :hugging_face: there’s so much cool stuff you can do with destructuring!
What does this mean?
@didibus cursive
https://user-images.githubusercontent.com/1011676/55212002-dfcbf080-51f6-11e9-8f0a-5bcb443b0086.png
I'm trying to create a nested outline of some seqs of strings. I have the feeling that it's going to be a 3 line function that I could spend all day trying to find.
The data looks like this:
(def stories
'(("Node" "is defined")
("Node" "breadcrumb" "links to the parent process")
("Node" "breadcrumb" "links to the parent workflow")
("Node" "breadcrumb" "when following the parent process link" "reaches the expected process")))
The desired output is something like this:
(def formatted-output
[:h1 "Node" [:ul
[:li "is defined"]
[:li "breadcrumb" [:ul
[:li "links to the parent process"]
[:li "links to the parent workflow"]
[:li "when following the parent process link"
[:ul
[:li "reaches the expected process"]]]]]]])
And this looks like it kinda helps but, it only does one level:
(update (group-by first stories) "Node" #(map rest %))
guys, how to access java enum in clojure ?
What's a good JDK version for a beginner to have installed?
ok ty
does clojure have problems with 11.0.2?
@diegoemericksousa An enum declaration inside a class is an inner class. You have to use the $
syntax to access it. For example: Locale$Category/DISPLAY
and the $ isn't a separator, it's part of the name
so import of Locale doesn't also import Locale$Category, that's a separate class
it worked, thanks @noisesmith
What's the idiomatic way to return a function that's the result of applying a default argument to the rightmost argument of another function?
Something like (partial)
but working like:
(partial-right clojure.string #" ")
Which would return a 1-arg function that splits the passed string on space. Is there something equivalent to (partial)
for this?I figured that might be the answer. Is there a reason behind why partial only works one way but not the other?
Things might get weird with variadic functions in the general case. Better to be explicit and not use it as a general pattern IMO
partial, if I recall, pre-dates the # syntax sugar, so it is possible if those happened in the other order partial wouldn't be in clojure.core at all
Gotcha. Thanks for the insight!
In Clojure, anonymous functions are considered to be more idiomatic than partial
I've been working on this problem all day: https://clojurians.slack.com/archives/C053AK3F9/p1555087933096000
after some experimentation I have determined, I definitely do not know how to use postwalk
i was kinda hoping I'd get somewhere with what might be mutual recursion, but, it doesn't quite get to the bottom of my tree
(def stories
'(("Node" "is defined")
("Node" "breadcrumb" "links to the parent process")
("Node" "breadcrumb" "links to the parent workflow")
("Node" "breadcrumb" "when following the parent process link" "reaches the expected process")
("Workflow" "is defined")))
(defn leaf? [parts]
(= 1 (count parts)))
(defn datafy-forest [forest]
(map (fn [[label parts]]
(if (leaf? parts)
[:li label]
(datafy-tree {label parts}))) forest))
(defn datafy-tree [tree]
(let [[label parts] (first (seq tree))]
[:li label [:ul (datafy-forest (group-by first (map rest parts)))]]))
(let [tree (dissoc (group-by first stories) "Workflow")]
(datafy-tree tree))
(let [tree (dissoc (group-by first stories) "Node")]
(datafy-tree tree))
the output of the last one looks so promising...
[:li
"Node"
[:ul
([:li "is defined"]
[:li
"breadcrumb"
[:ul
([:li "links to the parent process"]
[:li "links to the parent workflow"]
[:li "when following the parent process link"])]])]]
you aren't using postwalk?
it walks all the way to the bottom of the tree, then replaces each thing on the way back up using your function
here's the last thing i tried before i gave up on it: my idea was, maybe forget the data, just see if I can classify different nodes correctly, so the shape is what it I'd expect
(defn classify [node]
(cond
(string? node) :label
(= 2 (count node)) :leaf
:else :story))
(postwalk classify (group-by first stories))
so that's going to fail as it tries to replace collections with keywords
if it gets a thing that holds an object, you probably want to return a new thing that also holds similar things
perhaps not fail but rather return something useless
i'll come back to it.... I'm sure it's the right thing but I tried to get it to return, like, anything for an hour
i have a completely wrong mental model of what it does and couldn't really make heads or tails of the examples i found
user=> (clojure.walk/postwalk (fn [node] (if (map? node) (assoc node :foo 42) node)) {:a 0 :b {:x 12 :y [{} {} {}]}})
{:a 0, :b {:x 12, :y [{:foo 42} {:foo 42} {:foo 42}], :foo 42}, :foo 42}
it literally returns the thing that replaces each thing it finds in a tree, bottom up
(postwalk (fn [m] (if (leaf? m)
[:li m]
[:ul [:li (first m)]])) (group-by first stories))
that's much closer to reasonable, yes
do you never want the rest
of m if it's not a leaf?
so you should do something with (rest m) in that code - any data not in what your function returns is not in the result of postwalk
i can't even parse English at this point 🙂 I will read what you just said tomorrow, thanks
:thumbsup:
the idea (if this is clearer) is that (first m) implies "I don't want anything from m other than the first item"