Fork me on GitHub

During my challenge of making our code work with repl driven workflow, I found an odd problem where having functions named identically with core functions stops new versions from appearing in calling function, when crossing namespace boundaries. At first I though this is related deftypes, then to polylith's way of linkin deps.edns together, but it does actually appear with just one simple deps.edn


So if I have a function repro2/read or named anything else than read, but still a core function, another function repro/func-b does not "see" a new version of it, if I just eval (defn read) in its namespace. But if I re-eval func-b's definition, not just the buffer, it works


I've yet to determine if this could be a bug in nrepl or cider-nrepl, since that's the setup I have


During this cascade of problems I also learned that if I redefine a type with (deftype MyType), the helper function ->MyType will keep using the old version. Also a bummer for repl driven flow.


At this point this doesn't have much to do with polylith except the discussion here about refreshing namespaces vs just evaling things in the editor, but I don't really know where to go from this point 😕


Sure, that helps/works


Though still so that you need to run it after every change; it doesn't have similar effect to evaling the (defn func-b) separately


Ah, a friend commented that he can reproduce this without any files, just on command line, so it's not a nrepl problem


(I would strongly recommend not using c.t.n.r/refresh -- it is not needed and just adds complexity and fragility to your workflow)


@U8ZQ1J1RR I can't reproduce this. I started a plain Socket REPL -- no nREPL/CIDER stuff -- and in my editor I can "load file" on repro.clj and when I eval (func-b) I get the initial output; then I open repro2.clj and modify the read function and eval that top-level form into the REPL (I don't need to save the file here); then switch back to repro.clj and eval (func-b) and it shows the modified output as expected.


That is exactly what I would expect: I can re-eval a top-level form (a defn in this case) and when I call it via eval'ing code in another namespace, the new definition is invoked.


Yeah, that's how it should work


Does the pure clj version work for you too, the one where there are no files?


Yes, if you correctly use (in-ns 'repro2) and (in-ns 'repro) to switch to existing namespaces -- instead of using (ns repro2) and (ns repro) which will overwrite things.


(! 707)-> clj
Clojure 1.11.1
(ns repro2)

(defn read []
   (prn "Called repro2/read 1"))

(defn read2 []
   (prn "Called repro2/read2 1"))

(ns repro
  (:require [repro2]))

(defn func-b []
  (prn "Called func-b: 1")

repro2=> repro2=> WARNING: read already refers to: #'clojure.core/read in namespace: repro2, being replaced by: #'repro2/read
repro2=> repro2=> #'repro2/read2
repro2=> repro2=> nil
repro=> repro=> #'repro/func-b
repro=> repro=> "Called func-b: 1"
"Called repro2/read 1"
"Called repro2/read2 1"
repro=> (in-ns 'repro2)
#object[clojure.lang.Namespace 0x43b0ade "repro2"]
(defn read []
   (prn "Called repro2/read 2"))

(defn read2 []
   (prn "Called repro2/read2 2"))
repro2=> (in-ns 'repro)
#object[clojure.lang.Namespace 0x7b60c3e "repro"]
repro=> (func-b)
"Called func-b: 1"
"Called repro2/read 2"
"Called repro2/read2 2"
(the prompts disappear when pasting multi-line code into the REPL so it makes it a bit harder to follow)


I also notice that you are running 1.11.1. I've been holding off for a while to see if any other surprises are found, but I should try repro with that too.


I think there's a socket repl client for neovim, so I could try that as well


The Clojure version is unimportant for this situation.


(we've been running 1.11 alpha/beta/rc builds in production for a long time)


Ok, I'll look into the socket repl then


The socket repl client for vim is clunky, it can only eval files, not forms. But I can still get the problem reproduced by using that to reload the repro2 file and running (in-ns 'repro) (func-b) straight in the cli repl


What editor are you using? And if relevant, what plugins?


And to clarify, indeed using in-ns fixes the pure clj "version", it's now just editors that I can't get working


I use VS Code and Clover (for the Socket REPL; and Calva for all the static stuff).


I haven't used nREPL for many, many years at this point.