Fork me on GitHub

(.toInstant #inst "2022-04-15")
I like Instant because of the isBefore method. And I like to type in year month day somehow


you can add a custom data reader if you want #year-month-day "2022-04-15"


regarding isBefore, there's also the polymorphic compare function

(ins)user=> (compare #inst "2022-04-15" #inst "2022-07-21")

šŸ‘ 1
Dustin Reed Morado13:07:22

I am looking at some of the code in the Clojure Cookbook and this sample on I/O

Dustin Reed Morado13:07:41

(ns keystroke.core (:import [jline.console ConsoleReader])) (defn show-keystroke [] (print "Enter a keystroke: ") (flush) (let [cr (ConsoleReader.) keyint (.readCharacter cr)] (println (format "Got %d ('%c')!" keyint (char keyint)))))

Dustin Reed Morado14:07:48

Sorry bad at entering code in Slack, anyways it requires using lein trampoline to run in the REPL and I am wondering what the equivalent for lein trampoline is when using the Clojure CLI deps tooling?


leiningen starts two jvm instances: one for your code and one for leiningen itself. lein trampoline will exit the second jvm instance once the jvm for you code is ready. clojure cli runs only one jvm instance so there is no equivalent of lein trampoline. just start repl normaly

Dustin Reed Morado14:07:00

I am using CIDER and still I see that when I run show-keystroke from the REPL it hangs, is there something different about the nREPL in CIDER?


/tmp/ex via ā˜• v17.0.3 
āÆ clj
DEPRECATED: Libs must be qualified, change jline => jline/jline (deps.edn)
Clojure 1.11.1
user=> (import '[jline.console ConsoleReader])
user=> (defn show-keystroke []
  (print "Enter a keystroke: ")
  (let [cr (ConsoleReader.)
        keyint (.readCharacter cr)]
    (println (format "Got %d ('%c')!" keyint (char keyint)))))
user=> (show-keystroke)
Enter a keystroke: Got 113 ('q')!
it works when you start repl from the shell


Will page breaks (`^L`) in source files break anything in Clojure?


no, but it might confuse some editors. For example in emacs cider-eval-last-sexp evals next sexp instead of previous:

(defn foo [])

;; cursor is hear but and last sexp is ^
;; but my emacs evals the one below
(defn bar [])


I'm actually using them to take advantage of backward- and forward-page . That's interesting. And using C-x C-e instead of C-c C-c evaluates the first form. So you can choose which one you want to be eval'ed.


Is there some reason data files in a folder on the classpath would affect REPL startup times? I had a few large CSV files in a resources/data folder in my project and it was taking nearly 90 seconds to start a REPL, after removing them it drops back to 15-20 seconds. I can understand why it would impact something like uberjar creation, but I don't have an intuition for why clojure/java is reading those files during startup.


normally no, but maybe a namespace or class you're loading is scanning for and reading those files?


you can dump your stack traces by hitting Ctrl + \ or calling jstack $PID on the JVM


if you catch it during the slow load, you might see a thread (probably "main") with a culprit trace


if you do catch a library/tooling doing that, it is likely a bug, because resources/ is stuff that should be loadable via a classloader, which doesn't allow for scanning


Thanks, I think I found it. It's a kit-clj project which seems to use lambaisland/classpath to monitor for deps changes and that ultimately uses which hashes all the files it's monitoring. Removing the watch-deps call from my user.clj stops the CSV files from being read


ah interesting, that wouldn't be a bug I guess, because it needs to watch them


it still seems like a bug though because the docs seem to indicate it only watches the deps.edn file, not everything in the classpath


it would need to watch everything


I have a map, and I want to conj something into a key that might not exist, this works:

(let [vm {}]
   (update vm :output conj 5))
;=> {:output (5)}
But I get a list out, is their a way to make it a vector ?


(let [vm {}]
    (update vm :output (fnil conj []) 5)
Perfect, thanks! šŸ˜„


Or maybe not, I think I am confusing the lambdaisland project with something else

Jim Strieter19:07:07

Is there an idiomatic way to randomly pick 1 item from a set? I want a set version of this:

(loop [some-list (whatever ...)
       results '()]
  (if (empty? some-list)
      (recur (rest some-list)
             (conj results (calculate-something (first some-list))))))
Obviously first and rest don't work on set. What might I use instead?


Why does it need to be a set ? If you just want to start with a collection, then randomly take items and do stuff, you could shuffle it first, then just map over it ? Something like:

(let [xs (shuffle (range 100))]
    (map (fn calc-something [n] n) xs))

Jim Strieter19:07:49

It needs to be a set because I need to perform set operations. Right now my algorithm takes a list and converts it to a set to do unions, intersections, etc. Converting lists to sets and sets to lists is killing performance. Then I realized if I could just operate on sets the performance problems would go away.


converting sets -> seqs should not kill performance, but the opposite would


would like to hear more about the problem at hand


i don't think there is a lot of performance difference between doing set -> seq -> set instead of just set -> set.


first does work on sets, is suppose by converting to a seq, but i don't think it is much slower. Instead of rest you can remove the element from the set with disj.

(loop [some-set (whatever ...)
       results '()]
  (if (empty? some-set)
      (recur (disj some-set (first some-set))
             (conj results (calculate-something (first some-set)))))


Off topic: ah, the axiom of choice, which I cannot comprehend!


first/rest absolutely work on sets

Jim Strieter19:07:36

It's fine if they're not random


but rest on a set gives you a list.

Jim Strieter19:07:15

I feel silly for not trying that out. The name "first" implies order, and sets don't have order, so I assumed first would not work on a set. Same for rest.

Alex Miller (Clojure team)19:07:56

sets (all Clojure colls really) are seqable, that is they can provide a logical list view of the data

Alex Miller (Clojure team)19:07:16

and seq functions (like first, rest, etc) always get a seqable view before doing the operation