This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-20
Channels
- # announcements (5)
- # asami (7)
- # babashka-sci-dev (36)
- # beginners (50)
- # calva (47)
- # cider (1)
- # clj-kondo (19)
- # clojure (33)
- # clojure-europe (25)
- # clojure-nl (2)
- # clojure-uk (4)
- # clojurescript (26)
- # conjure (2)
- # cursive (5)
- # datalog (6)
- # fulcro (5)
- # graalvm (12)
- # leiningen (1)
- # malli (30)
- # off-topic (5)
- # rdf (4)
- # ring (11)
- # shadow-cljs (55)
IDE question: I recently heard that http://github.blog/2022-06-08-sunsetting-atom/, which makes me super sad. I guess VS Code + Calva is the closest alternative? How similar are the two? Besides some really great editor themes, my Atom setup is pretty low-key: Paredit, Parinfer + rainbow parens, Chlorine, and occasionally clj-kondo.
There's actually a huge force behind Atom-Community right now trying to keep everything alive. It'll probably be rebranded, but we'll probably be able to keep the editor alive, hopefully
If you want to follow things, I have a fork where I'm also trying to renovate some elements (like Electron versions): https://github.com/AtomRebirth/atom
Probably really soon I'll start to publish somewhat "nightly" packages too
@UGHNF0CS3 if you're not already in the #chlorine-clover and #atom-editor channels, you should join those.
If I have a map and want to extract values associated with keys which in turn comes from a vector of keys (while retaining the order), I would do:
(let [temp-map {:x 1 :y 2 :z 3}]
(reduce (fn [acc key]
(conj acc (temp-map key))) [] [:y :x :z]))
;; => [2 1 3]
Is there a core function that achieves this behavior?Oh, the whole reduce ..
logic is actually mapping a function; why did I overlook it..??
Actually it might be fun to write a linting rule that swaps reduce
calls to map
or filter
wow, in this case the keyword is playing the callable role.
yeah, think of keywords as "data extractor functions", and juxt as a way to make a function that applies multiple data extractors
Hi! I’m trying to debug a go-loop
(using intellij and cursive) but when I place a breakpoint inside the loop I get an error that says there is no executable code found on that line. Is there something I can do to make this line debuggable?
(defn func []
(go-loop []
(let [x (<! c)]
(println "Got a value in this loop:" x))
(recur)))
(Placing a breakpoint on the println
line)Oh, why is that?
I’m guessing if I export the inner part of the loop to a function I can debug that, right?
The go macro completely tears apart your code, I don't know how a debugger would even begin there So changing the approach - what is your goal?
Ideally you wouldn't need a debugger there , so I'm trying to follow from the root need which led to the conclusion of "I want to debug this"
I was hoping to add the capability of debugging go-loops, and wanted to understand if I’m missing something and if there are any debuggers out there that already implement it.
I’ll take a look, thanks so much!!
Generally I try to keep go blocks as tiny as possible, calling out to regular functions, exactly because the macro makes the code incomprehensible
something that helps a lot here is log oriented rather than step-oriented debugging. you can use add-tap
and tap>
to capture immutable data in context and append to an atom, then browse the values in order, and experiment with them as needed.
(cmd)user=> (def captured (atom []))
#'user/captured
(cmd)user=> (defn capture-data [[k v]] (swap! captured conj {k [(System/currentTimeMillis) v]}))
#'user/capture-data
(ins)user=> (for [i (range 10)] (do (tap> [:outer {:i i}]) (for [j (range 10)] (do (tap> [:inner {:i i :j j}]) [i j]))))
(([0 0] [0 1] [0 2] [0 3] [0 4] [0 5] [0 6] [0 7] [0 8] [0 9]) ([1 0] [1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [17] [1 8] [1 9]) ([2 0] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9]) ([3 0] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [3 8] [3 9]) ([4 0] [4 1] [4 2] [4 3] [4 4] [4 5] [4 6] [4 7] [4 8] [4 9]) ([5 0] [5 1] [5 2] [5 3] [5 4] [5 5] [5 6] [5 7] [5 8] [5 9]) ([6 0] [6 1] [6 2] [6 3] [6 4] [6 5] [6 6] [6 7] [6 8] [6 9]) ([7 0] [7 1] [7 2] [7 3] [7 4] [7 5] [7 6] [7 7] [7 8] [7 9]) ([8 0] [8 1] [8 2] [8 3] [8 4] [8 5] [8 6] [8 7] [8 8] [8 9]) ([9 0] [9 1] [9 2] [9 3] [9 4] [9 5] [9 6] [9 7] [9 8] [9 9]))
(ins)user=> (count @captured)
110
(cmd)user=> (nth @captured 55)
{:inner [1656691454460 {:i 4, :j 5}]}
(ins)(user=> (->> @captured (drop 54) (take 10))
({:inner [1656691454460 {:i 4, :j 4}]} {:inner [1656691454460 {:i 4, :j 5}]} {:inner [1656691454460 {:i 4, :j 6}]} {:inner [1656691454460 {:i 4, :j 7}]} {:inner [1656691454460 {:i 4, :j 8}]} {:inner [1656691454460 {:i 4, :j 9}]} {:inner [1656691454460 {:i 5, :j 0}]} {:inner [1656691454460 {:i 5, :j 1}]} {:inner [1656691454460 {:i 5, :j 2}]} {:inner [1656691454460 {:i 5, :j 3}]})
user=>
and I accidentally made a nice demo of counterintuitive chunking behavior
(ins)user=> (->> @captured (map #(cond (:outer %) :outer (:inner %) :inner :else :huh?)))
(:outer :outer :outer :outer :outer :outer :outer :outer :outer :outer :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner :inner)
(cmd)user=>
I’m getting intermittent erorrs when using this technique to dynamically load namespaces.
(require ns-sym) (the-ns ns-sym)
Every once in a while a JVM process will spin up and throw No namespace: <ns-sym> found
errors. Any idea what would cause this problem and how to resolve it?For dynamic ns loading I tend to use https://github.com/borkdude/dynaload
There's also https://clojuredocs.org/clojure.core/requiring-resolve if that's your thing - not entirely sure what your goal is, so just dropping some links here 🙂
requiring-resolve
may be the solution… that’s a fairly new addition to clojure.core… Thanks for the link!
requiring-resolve
is thread safe, plain require
is not. There's a serialized-require
in core (behind requiring-resolve
) but I think it's private.
Thanks @U8SFC8HLP and @U04V70XH6. I’ve updated and testing the use of requiring-resolve
and so far it’s working great.