This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-11
Channels
- # announcements (4)
- # aws (6)
- # babashka (40)
- # beginners (318)
- # biff (4)
- # bootstrapped-cljs (9)
- # calva (19)
- # chlorine-clover (1)
- # cider (3)
- # clj-on-windows (25)
- # cljdoc (8)
- # cljfx (1)
- # cljs-dev (30)
- # cljss (2)
- # clojure (62)
- # clojure-chile (9)
- # clojure-europe (11)
- # clojure-finland (17)
- # clojure-italy (1)
- # clojure-kc (1)
- # clojure-nl (3)
- # clojure-spec (27)
- # clojure-uk (40)
- # clojuremn (1)
- # clojurescript (51)
- # conjure (6)
- # cursive (8)
- # data-science (9)
- # datahike (4)
- # datascript (1)
- # datomic (31)
- # emacs (10)
- # emotion-cljs (1)
- # events (1)
- # figwheel-main (16)
- # find-my-lib (1)
- # fulcro (30)
- # graalvm (3)
- # graphql (12)
- # helix (16)
- # honeysql (5)
- # jobs (1)
- # jobs-discuss (10)
- # juxt (3)
- # kaocha (26)
- # lambdaisland (3)
- # leiningen (15)
- # malli (7)
- # off-topic (100)
- # pathom (8)
- # pedestal (15)
- # protojure (24)
- # re-frame (2)
- # reagent (7)
- # reitit (22)
- # remote-jobs (1)
- # shadow-cljs (140)
- # spacemacs (17)
- # spire (2)
- # tools-deps (23)
- # uix (11)
- # vim (5)
- # xtdb (3)
- # yada (3)
I have noticed a convention of using user.clj
which requires in a dev.clj
ns like https://github.com/pedestal/pedestal/blob/239d2c7899ac3466a32ab124ab3850e56abeb0c5/app-template/src/leiningen/new/pedestal_app/annotated/dev/user.clj. Does anyone know why this is done vs. keeping everything in user.clj
?
user.clj is auto-loaded by clojure if it's on the classpath
dev.clj isn't "magic" in that way, so you have more direct control of when / whether it is loaded
It means you can avoid any/all dependencies that dev.clj
needs (as long as you don't call (dev)
). So you can isolate dev dependencies from "regular" dependencies.
I think the only thing I've ever used user.clj
for is auto-compiling a namespace that uses :gen-class
to generate a Java class from Clojure code, which the rest of the project relies on.
and as an aside, the idiom I've learned for (require 'foo) (in-ns 'foo)
is (doto 'foo require in-ns)

Ah, yes, nice.
easily augmented to (doto 'foo-test (require 'foo :reload) (clojure.test/run-tests))
when iterating on tests - it's still one line which is nice when using repl history
Ahhh, makes sense.
@seancorfield You mentioned you only use user.clj
for the :gen-class
use case. Does this mean that for your projects, you don’t setup a user
-> dev
reloaded workflow?
I never use any sort of automated reload/refresh workflow.
I eval every change, as I make it, directly into my running REPL and I run a REPL for many days, sometimes even weeks.
+1 to seancorfield - I do the same thing as Sean and have never used the reload/refresh workflow either. I understand how that came to be a thing but I think you can get many of the same benefits in other ways that don't need that.
if you spend some time in the clojure code base, user.clj is deeply weird and different than how every other thing is loaded in Clojure. I prefer to write dumb boring code that does obvious things and invoke it when I want to run it.
I have not asked, but I suppose that one property of Sean's approach is that if you ever forget to re-eval a modified function, then the JVM state and source file state now differs, so it does require some pretty tight discipline. Perhaps an attractiveness of a reloaded workflow style for some developers is the belief/hope/often-true aspect that it keeps these things in sync automatically?
I frequently reload the particular namespace I'm in
you can still get out of sync if you've removed things in the code but they're loaded in memory. I rarely find that to be an issue and since I'm constantly evaluating things.
Where can I read more about this "automated reload/refresh workflow"? Is it what's described here? https://lambdaisland.com/blog/2018-02-09-reloading-woes
@dromar56 yep. Also see this: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded.
To Alex's point about things remaining in memory after you've removed them from code, even if you reload the namespace, I have ctrl-; r
bound to remove-ns
but I only use it very occasionally because you can still have references to that code compiled elsewhere so it's sort of the "nuclear option" (and it's part way toward those refresh/reloaded workflows I try very hard to avoid).
I also have ctrl-; R
bound to require ,,, :reload-all
for the current namespace. Again, it's a bit of a "nuclear option" that I try to only use as a last resort. Both remove-ns
and :reload-all
can cause a ripple effect, depending on how much code you have in memory.
I tend to edit, ctrl-; B
(evaluate top-level block/form), repeatedly as I'm working -- without even saving a file -- trying stuff out with expressions inside comment
forms ("Rich Comment Forms" per Stu H), switching between files as I work, developing and testing code, developing and testing tests, etc. Once I have a "feature" working in memory, in the REPL, I'll pop into a terminal window and run a subset of the test suite to just verify I don't have passing tests in memory due to leftover "cruft". If that small feature works, then it's git add/commit/push to branch. Rinse and repeat.
I also make heavy use of Cognitect's REBL while I'm working, both to visualize data and to "visualize code" -- I have a bunch of keys bound to commands that submit various things to REBL so I can browse namespaces, Var uses, even ClojureDocs and Java API docs directly in REBL (since it renders
objects as HTML web pages -- and then you can navigate around with your current and previous pages showing, side-by-side).
I work in the REPL but have setup a namespace to invoke tools...refresh (can’t remember the exact namespace) to remove everything and go back to source files. Useful if you mess something up real good, when switching branches, to just sanity check if something appears off.
@orestis So you consider it a "last resort"? (I hope)
Despite reading all that I saw from time to time on the topic, I still fail to see the appeal of manual reloading. To me, it's like driving a stick. Needless to say, I got a driving license only for an automatic. :)
"fail to see the appeal of manual reloading" -- control and simplicity.
(I'd much rather drive a stick shift!)
(esp. when that was a 5L Mustang Cobra 🙂 )
Sorry, a correction: "... of manual reloading at all times". I understand the occasional need, and even I do use that (but only if the automatic reload didn't get those pesky defrecord
s). But all of the time? Nooo, let the system take the wheel.
I think this is not directly connected to Clojure, but I stuck with this. I was trying to get help in more cloud specified community, but without success. Maybe somebody here know solution:
curl -H "Content-Type: application/json" -d '{"foo":"bar"}' -X GET
curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
http-kit logs
Thu Jun 11 13:23:15 CEST 2020 [client-loop] ERROR - select exception, should not happen
java.lang.IllegalStateException: Client/Server mode has not yet been set.
at java.base/sun.security.ssl.SSLEngineImpl.beginHandshake(SSLEngineImpl.java:102)
at org.httpkit.client.HttpClient.finishConnect(HttpClient.java:395)
at org.httpkit.client.HttpClient.run(HttpClient.java:472)
at java.base/java.lang.Thread.run(Thread.java:832)
Thu Jun 11 13:23:15 CEST 2020 [client-loop] ERROR - select exception, should not happen
java.lang.IllegalStateException: Client/Server mode has not yet been set.
at java.base/sun.security.ssl.SSLEngineImpl.beginHandshake(SSLEngineImpl.java:102)
at org.httpkit.client.HttpClient.finishConnect(HttpClient.java:395)
at org.httpkit.client.HttpClient.run(HttpClient.java:472)
at java.base/java.lang.Thread.run(Thread.java:832)
but exactly the same code in the same docker image works in my local environment.
The issue is about -d '{"foo":"bar"}'
.
Without this:
curl -H "Content-Type: application/json" -X GET
not found⏎
^ expected result
AFAIK google cloud run use HTTP/2. Does it change anything? Any hints what I can do wrong?
In metric and logs I see google cloud run break this connection before it goes to the docker container. This is something about network protocol probably. But it doesn’t work for me in http-kit client and in curl. hmm. No idea what to do with this.well I have no idea, but it looks HTTP/2 send request GET with body is not something valid. At least in google cloud.
I don’t know if anyone noticed https://jet-start.sh/blog/2020/06/09/jdk-gc-benchmarks-part1
what’s the easiest, tersest way to update a map with default values for keys that are nil?
well I'd put my effort into not putting nils in the map in the first place then (merge defaults the-map)
If for some reason you really need the nils, you can do (merge-with defaults the-map (fn [default-val val] (if (some? val) val default-val)))
Is there a way to use into
along with a transducer that has two input sequences?
For example:
(into [] (mapcat vector) [:x :y :z] [1 2 3])
the only transducing context that takes multiple inputs is sequence
conceptually, there is no reason this couldn't exist (and the guts are already there, as used by sequence) - but the arities collide in all the existing sequence functions like map
and mapcat
the existing map
transducer (and thus also mapcat
, as it's just a composition of map
and cat
) does support multiple inputs, that's just not exposed through into
etc
whats the ideal way to write a clojure data stucture to an .edn file? it seems like i should use pr-str then spit. but i dont see anything definitive on the subject. just trying to avoid any gotchas. bonus points if there is a way to save it in a formatted way...
pprint takes a writer arg
nicee...
Or re-bind *out*
around pprint
I am using boot instead of lein. I was used to doing lein ancient
to check outdated dependencies. What could I use to get the same result in boot?
Thank you, @dpassen1