@nate @neumann I had just sent this to a friend at Adobe who I’m helping learn Clojure — we’re using it with ClojureMCP from @bhauman.
I had just listened to all three episodes this morning, and again, marveled at how amazing that first episode described my slow aha moment learning about REPL. It was hilarious to me how it was equally delightful on my 3rd (or 4th) listening.
But I heard something that made me almost fall over. You mentioned about how clojure.tools.namespace.repl/refresh could eliminate need for JVM restart for defprotocol, deftype, defrecord — very literally, earlier this year, I was cursing at the need to restart the JVM when I changed these things in a certain way. (Presumably because the Java .class files wouldn’t be picked up.)
Could you confirm that refresh actually allows dynamic redefinition of these things that makes more easier and less painful to use? TY!!!!
Thank you, @trost.mario — I will definitely check it out! I'm so glad I re-listened to that podcast episode, because I'm hoping to learn how to use some of these more Java-esque class stuff without some of these downsides. I'll keep y'all posted!
@genekim It looks like much faster and smarter people than me have already answered the tech question. I will say that I would love to make a video version of those episodes. Thanks again for your encouragement and feedback!
I’ve gotten into the habit of having these terminal applications have a reload-all command that reloads all the namespaces.
I’m starting to realize I should have used refresh instead….
ct.namespace is a huge workflow changer, it's not without issues but it works way better than :reload/:reload-all
the few places where you have to be careful are:
• protocols & record instances
• mixing tnr.refresh and :reload - you'll run into issues with namespace aliases and such
over the years I built a small library of REPL helpers to avoid most of these, or at least help with recovering from various broken states - to a point where I rarely restart anything, unless dependencies change (because I'm mostly using Leiningen at work, and it doesn't work with add-lib )
TY! So, if I change defrecord, and then use tnr.refresh, it will do all the right things?
(I will try it later today, but I have such negative associations using it, because I now associate it with “oh great, now I have to restart my REPL!” 😂 )
yes, that will work - issues start if you hold on to an instance of a record which implements a protocol, you refresh your code (changing the protocol or its impl in the record), and try using that stale record against updated protocol - you'll get an exception because protocol cache was busted - so you always have to make sure you rebuild your records after refresh
@genekim Have you ever tried https://github.com/tonsky/clj-reload? afaik it’s smarter than tools.namespace, but I actually don’t know if it solves your problem. It does have a comparison section https://github.com/tonsky/clj-reload?tab=readme-ov-file#comparison-toolsnamespace