IDeref / IAtom now implementable in user code on sci master: https://twitter.com/borkdude/status/1306206133539999745
Hi I have a little question regarding eval-form. It's said to bind sci/ns
with sci/binding
. I have try the following which works:
(def program
'(let [current-ns (-> *ns* str symbol)]
(ns foo)
(defn bar [x] (inc x))
(in-ns current-ns)
(require 'foo)
(foo/bar 1)))
(def env (sci/init {}))
(sci/binding [sci/ns sci/ns]
(sci/eval-form env program))
Is this the proper use of the binding requirement? sci.impl.interpreter/eval-string*
goes with something like:
(vars/with-bindings {vars/current-ns @vars/current-ns}
@jeremys (sci/binding [sci/ns @sci/ns] ...)
so: bind sci/ns to the current value of sci/ns
sci/ns is a sci var, not a normal var, that's why you have to deref is explicitly
the reason for the binding is the same as in clojure: set! is only allowed when there is already a thread-local binding
@jeremys ns switches aren't supported in let forms, only top level or in top-level do:
(require '[sci.core :as sci])
(def program
'(do (ns foo)
(defn bar [x] (inc x))
(ns user)
(require 'foo)
(foo/bar 1)))
(def env (sci/init {}))
(sci/binding [sci/ns sci/ns]
(prn (sci/eval-form env program)))
Note that that doesn't work in normal Clojure either:
(let [current-ns (-> *ns* str symbol)]
(prn current-ns)
(ns foo)
(defn bar [x] (inc x))
(in-ns current-ns)
(require 'foo)
((resolve 'foo/bar) 1))
but this on the other hand does work:
(do
(ns foo)
(defn bar [x] (inc x))
(in-ns 'user)
(require 'foo)
(prn ((resolve 'foo/bar) 1)))
Ok thanks! Having reified environments, eval, macros is pretty powerful but sometimes it is confusing, especially playing with sci witch adds another layer of environment, eval and macros... It's fun though!