Search code examples
clojure

Why namespace inside a go block changes?


(ns myapp.core
  (:require
   [clojure.core.async :refer [>! <! >!! <!! chan go-loop]])
  (:gen-class))

(def this-ns *ns*)

(defn get-ns [c0]
  (go-loop []
    (let [x (<! c0)]
      (println (str "this ns     -> " this-ns))
      (println (str "go block ns -> " *ns*)))
    (recur)))

(defn -main [& args]
  (let [c0 (chan)]
    (get-ns c0)
    (>!! c0 1)))

Output:

this ns     -> myapp.core
go block ns -> user

Can anyone explain why the namespace is different inside the go block?


Solution

  • I don' think this has to do with core.async. It's just how *ns* works - it contains the current repls current namespace

    clojure.core/*ns*
       A clojure.lang.Namespace object representing the current namespace.
    

    in other words, *ns* is dependent on the namespace you are calling from

    Example:

    ; <current-ns>=> <code>
    
    user=> (load-file "yourcode.clj")
    #'myapp.core/-main
    
    user=> (myapp.core/-main)
    this ns     -> myapp.core
    go block ns -> user
    true
    
    user=> (in-ns 'myapp.core) ; <-- switching namespace 
    #object[clojure.lang.Namespace 0x679e26fe "myapp.core"]
    
    myapp.core=> (-main)
    this ns     -> myapp.core
    go block ns -> myapp.core
    true