This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-29
Channels
- # announcements (1)
- # babashka (15)
- # beginners (37)
- # calva (94)
- # cider (3)
- # clj-kondo (17)
- # cljsrn (2)
- # clojure (45)
- # clojure-europe (39)
- # clojure-germany (1)
- # clojure-norway (2)
- # clojurescript (16)
- # component (18)
- # conjure (1)
- # cursive (13)
- # datalevin (3)
- # datomic (12)
- # docker (2)
- # duct (5)
- # eastwood (2)
- # emacs (4)
- # events (8)
- # fulcro (8)
- # inf-clojure (5)
- # kaocha (8)
- # lsp (24)
- # malli (11)
- # meander (3)
- # off-topic (19)
- # polylith (11)
- # remote-jobs (4)
- # sci (61)
- # shadow-cljs (9)
- # spacemacs (34)
- # sql (10)
- # tools-deps (27)
- # xtdb (10)
So I apologize - I didn't mean to privately message you before about how to manage namespaces when coding a repl using sci
- you very kindly replied with the following code:
(def !last-ns (volatile! @sci/ns))
(defn eval-string [s]
(sci/binding [sci/ns @!last-ns]
(let [rdr (sci/reader s)]
(loop [res nil]
(let [form (sci/parse-next @!ctx rdr)]
(if (= :sci.core/eof form)
(do
(vreset! !last-ns @sci/ns)
res)
(recur (sci/eval-form @!ctx form))))))))
I'm not using that code quite yet, but if I try something like (ns client)
in my repl, I get the following error, and I'm curious what's causing it:
Maybe if I used the code you showed, that somehow wouldn't happen but if that's the case, I'm confused.
@pmooser The problem is that (ns client)
will change the value of the dynamic var *ns*
but it may only be changed inside a binding. eval-string
and eval-string*
do that automatically, but eval-form
does not
Ok great - that does indeed fix it. Now I'll integrate the rest of what you gave me. Thanks - I have things almost perfectly working I think ...
@borkdude In cljs, what's the practical difference between using a volatile vs. storing a value in an atom ?
@pmooser volatile is a light weight atom with less features and therefore a bit more performant
Sure, but given that performance in a repl (between entered data) is sort of gated by typing speed, it seems like that difference isn't materially important here. In any case, it sounds like it isn't required, but I appreciate the additional info!
"less features" means not thread safe and should be used only in isolation.
oops, sorry ) too many channels )
With "here" I mean in the context of @pmooser’s question, not this channel > In cljs, what's the practical difference
Given a sci
context, is there a way to say "what is the sci namespace for symbol x
" ?
(outside of sci itself ... I'm trying to put bindings together for the very first call to the sci evaluator ... once I've been through there, it's not really a problem)
I suppose I could eval something and get sci to return the namespace, but it seems like there must be a better way.
@pmooser There currently isn't a better way than eval-ing something :)
But I guess we could expose (sci/find-ns ctx sym)
?
I suppose I shouldn't be afraid of eval-ing something - I just have written my own interface (since my use of sci is an adaptation of something I used to have) and I have a symbol in hand which corresponds to the namespace I want, but the actual place the namespace gets created is "somewhere else" (where I'm creating namespaces and copying existing cljs namespaces), so what I have easy access to is simply the ctx ...
I also don't know enough about the sci representation of namespaces to do anything other than call "eval" safely, since I don't know exactly how they evolve over time.
indeed, the representation inside the context is subject to change, but the outer API should remain stable
Do you think it's sufficiently "safe" (from an API stability point of view) to do something like:
(keys (:namespaces @(:env sci-ctx)))
to find the list of namespace (symbols) that sci knows about?
@pmooser There is a better way, which is to evaluate (all-ns)
- I could also expose that one, just a moment
@pmooser Something like this?
user=> (require '[sci.core :as sci])
nil
user=> (def ctx (sci/init {}))
#'user/ctx
user=> (def all-nss (sci/all-ns ctx))
#'user/all-nss
user=> (map sci/ns-name all-nss)
(user clojure.core clojure.set clojure.edn clojure.repl clojure.string clojure.walk clojure.template)
Ok, I imagine I'm doing something wrong.
So I create my namespaces and I have my context. Then I pull out a specific namespace (based on a config file), which in this case is user:
(sci/find-ns sci-ctx (:default-ns repl-config))
That returns the right ns, which has the right name.
However, when I call sci
to evaluate something, I set up bindings like this:
(sci/binding [sci/ns (:current-ns @state)] ...)
And when I call eval, after I do the eval, if I ask sci/ns
for its name, I get *ns*
(let [ns (sci/find-ns (:sci-env @state) 'user)]
;; prints "user"
(println "1: name ns" (sci/ns-name ns))
(sci/binding [sci/ns ns]
;; prints "*ns*"
(println "2: name ns" (sci/ns-name sci/ns))))