This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-11
Channels
- # announcements (14)
- # beginners (119)
- # boot (9)
- # calva (7)
- # cider (12)
- # cljdoc (2)
- # cljsrn (28)
- # clojure (127)
- # clojure-dev (2)
- # clojure-europe (3)
- # clojure-italy (2)
- # clojure-losangeles (9)
- # clojure-nl (6)
- # clojure-spec (15)
- # clojure-uk (39)
- # clojurescript (35)
- # community-development (4)
- # cursive (9)
- # datascript (8)
- # datomic (5)
- # duct (3)
- # emacs (10)
- # fulcro (45)
- # graphql (3)
- # jobs (1)
- # kaocha (8)
- # luminus (2)
- # off-topic (121)
- # onyx (3)
- # pathom (15)
- # pedestal (31)
- # planck (5)
- # reagent (25)
- # reitit (3)
- # remote-jobs (1)
- # shadow-cljs (48)
- # slack-help (1)
- # sql (142)
- # tools-deps (78)
don't know how I missed you could write a name spaced keyword like this :addr/addr
š
Iām using Paredit for Atom. Is there a name for this operation? Take a sexp to the next higher level, outside of the current sexp. Canāt seem to do it with barf or slurp.
Before
(when (and (= 2 (degree pnml) (prime? p)))
After
(when (and (= 2 (degree pnml)) (prime? p))
That's barf @tabidots -- you have lisp-paredit installed in Atom?
Yes, Iām using lisp-paredit. Trying to figure out what the keyboard shortcut symbols mean is a nightmare though
Oh, I see. The cursor has to be in the sexp you want to barf from, not the sexp you want to move
The sexp editing sentences read pretty funny even after a week of not doing Lisp š
I want to read a bunch of rows from DB, do operations and insert results to another table. Some other cron job is inserting into first table so Iāll have an endless amount of stuff to work on. Code looks something like:
(doseq [x (get-things-from-db)]
(do-work-on x))
I want to make this start/stop with Mount along with the rest of my application. To make it stoppable, I thought about putting it in a future and calling future-cancel on :stop key. Is this the right way to approach this problem?I feel sooo stupid - can't solve ProjectEuler exercize #3 (find some number prime factors) in Clojure for weeks. Could you give me some hints? I decided to create a lazy sequence of all prime numbers and then find the biggest prime factor of a given number (there is another way, I know - to divide the given number until it's 1)
Hi folks, I have a question about how to orchestrate some core.async go blocks/threads. For example I want to build a simple telnet client like app. It has a connection, and a loop that constantly tries to read from the connection in a go block, and another loop which constantly reads input from stdin and then writes the input to the connection. The problem is, how do I cancel one loop from the other loop, like when I type āctrl + cā I want to terminate the loop that reads from the connection, and terminate the loop that reads from stdin when the connection is closed.
Well first, go blocks shouldnāt block on io, so use a loop in a thread instead
To communicate between threads of control, you need a means of signaling, so make a control channel
Thanks for the quick reply. Is there some code example of this pattern you could point me to?
Also note that Clojure has a built in socket server that does a lot of what you describe already
@gr.evocatus Rather than a sieve or lazy sequence, I found it easier to implement prime?
as a primality tester, and use that as a filtering function. For example, (filter prime? (range 1 (inc 100)))
gives me the primes from 1 to 100.
In order to check for primeness you need to try to divide this number by all prime numbers below it. Do you use some caching (explicit or implicit)?
I did not bother trying to divide by all prime numbers below n
. I have a cond
that tests whether n
is <= 1
, = 2
or even?
, then loops through all odd numbers from 3 to sqrt(n)
to test divisibility. Thatās the naive fn. Then I memoized it.
I did also implement isqrt
(integer sqrt) function with an algorithm I donāt understand (found on SO) to speed things up for very large n
(like > 1E24
)
You can get decently fast results even with this simple approach. Sieves and lazy-seq approaches to prime generation are certainly doable in Clojure, but are incredibly complex and nearly unreadable
Thanks for the quick reply. Is there some code example of this pattern you could point me to?
@gr.evocatus I couldnāt post a code snippet in the thread, but this is my implementation. If your n
is smaller than 1E24
-ish then tower/sqrt
+1 or Math/sqrt
+1 should work fine for the upper bound.
btw, I tried refactoring the loop-recur with some
, but itās slightly slower
is there a standard function that drops non-unique values from a collection? like `=> (the-thing-i-want [1 2 3 3 4]) [1 2 4]`
I can't quite work out what to search in google to find what I want lol
(remove #(= 3 %) [1 2 3 3 4 5])
=> (1 2 4 5)
Like that?
or you want to filter anything that appears more than once?
yeah i want to filter out anything that appears more than once while still keeping the same order of values if possible
looks like your snippet does that
thanks a lot
oh wait no i see
Not quite, it only removes 3's
i see now
but itās not too hard to write a fn that does what youāre saying.
exactly
you can use a set
yeah me too but then how do i get the original order back
you're right that'll do it
thank you
is exactly this
dedupe doesn't remove the non-uniques entirely
it just makes everything appear once
i think we got confused if consecutive was a part of this. i've never used dedupe
. Love this channel'
sorry i'm probably explaining what i'm looking for badly lol
I couldn't find anything in the documentation that said frequencies
would preserve order - it's probably an implementation detail that I wouldn't rely on
I was thinking something along the lines of
(defn drop-repeated [xs]
(let [to-drop (->> xs
(frequencies)
(filter #(> (val %) 1))
(keys)
(into #{}))]
(remove to-drop xs)))
just as an aside, (frequencies)
, (keys)
here don't need parens around them - ->>
will do that for you
but some people like the way it reads better, so no big deal either way
and (into #{})
could just be set
Also come to think of it, I often use (into ***)
instead of the plain constructor as a sort of idiom signalling that the collection type is being changed, not sure if there's any practical difference there
isn't using set
the same signal? (even better, it's basically a no-op, so faster, if it isn't a change)
I view it as a statement assuring final type (and set
/ vec
) are optimized for more special cases than into
around this
Thanks! I didn't realise there would be a performance difference there - time to change some of those habits š
frequencies returns a map which has no concept of order. as an implementation detail, it is ordered up to 8 i think and then switches to an unordered version. don't rely on this though
you should consider it unordered and subject to change
is there a simple way to subtract a collection from another collection?
something like (remove '(2 3) '(1 2 3)) => (1)
except actually works
(remove #{2 3} [1 2 3 4])
=> (1 4)
Just make the collection you want to remove into a set.
oh jesus thats easy
thank you
another set-related question, does anyone know the name of this operation which takes a collection of overlapping sets and merges them into mutually non-overlapping sets?
I've been trying to google this for a while, can't seem to find a standard name or algorithm for it
sounds almost like clojure.data/diff or I might misunderstand completely
user=> (clojure.data/diff #{:a :b :c} #{:c :d :e})
[#{:b :a} #{:e :d} #{:c}]
to do that you are going to have to iterate over all the sets multiple times, slowly merging them, and you will only know you are done when the output stops changing
the clever way is likely to not generate sets that you need to merge that way in the first place
it's the subgraph algorithm in disguise, right?
graph partitioning
where two sets having an element in common is an edge
that's where I'd look for a fast implementation, if any existed
{a #{0 2} b #{0} c #{1 2} d #{1} e #{3} f #{3}}
has the same information as the sets in your example
that's basically my problem- looks like graph partitioning is the direction to explore, thanks!
hmm, now learning that the graph partitioning problem is NP-complete, I'm very suspicious about my polynomial-time solution that I had before, even if it was quadratic.
@qythium I worry that "partitioning" was imprecise here, because most graph partitioning is about finding edges to remove in order to create a subgraph, not detecting already distinct subgraphs
the latter, what you need, is a much less complex task
what you want, I think is "find all mutually vertex disjoint subgraphs" - the hard part is wading through the interesting and harder algorithms to find that simpler one I think
here's my current implementation if anyone's interested to take a look:
(defn merge-sets [sets]
(loop [reacted #{}
[s & unreacted] sets]
(if-not s
reacted
;; react the first unreacted set with the already reacted ones
(let [reacted*
(loop [acc #{}
reacting s
[r & rs] reacted]
(if-not r
(conj acc reacting)
;; if r shares an element with the set being reacted
(if (seq (set/intersection reacting r))
;; merge them
(recur acc (set/union reacting r) rs)
;; ignore it
(recur (conj acc r) reacting rs))))]
(recur reacted* unreacted)))))
(merge-sets '#{ #{a b} #{c d} #{a c} #{e g f} })
;; => #{#{e g f} #{a c b d}}
what would it do for #{{a b} #{b c} #{d e} #{e f} #{g h} #{h i}}
I don't think that code could generate #{#{a b c} #{d e f} #{g h i}}
which I think is the answer?
yup, it does:
(merge-sets '#{#{a b} #{b c} #{d e} #{e f} #{g h} #{h i}})
;; => #{#{e d f} #{i g h} #{a c b}}
oh! I misread the code, nice