i am running into weird differences in SCI name resolution depending on whether a bound host function is involved or not. here is a simple example that reproduces the problem:
(sci/eval-string "(ns xxx) (def y :y) (ns user) (identity (do (use 'xxx) y))")
that throws an exception that says Could not resolve symbol: y. but if i remove the identity call, it works fine:
user=> (sci/eval-string "(ns xxx) (def y :y) (ns user) (do (use 'xxx) y)")
:y
why the difference here? is there simple way to avoid this?note that identity is clojure.core/identity, i.e. it is bound from the host
oh hm this is not related to host functions at all; this reproduces the issue:
user=> (sci/eval-string "(ns xxx) (def y :y) (ns user) (defn my-identity [x] x) (my-identity (do (use 'xxx) y))")as a workaround i can wrap the do in eval but that causes me trouble for other complicated reasons and i would rather not have to
oh huh this doesn't seem related to SCI at all. i can reproduce this in the host
> oh huh this doesn't seem related to SCI at all. i can reproduce this in the host 👍 AKA https://technomancy.us/143
that's very helpful, thanks 🙂 i think i can contort my code so it always has a top-level do, let me try that now
note that macros evaluating to do do work:
$ clj -M -e "(ns xxx) (def y :y) (ns user) (defmacro foo [x] x) (foo (do (use 'xxx) y))"
#'xxx/y
#'user/foo
:yand i remember that sci has a way to bind host macros, yeah ... i'll keep that in mind, thanks 🙂
i keep having this pattern show up in my codebase:
; NOTE: parse-string only parses a single form, so we have to wrap the file in `do`
(let [lisp (str "(do " f ")")
form (sci/parse-string cx lisp)]
) ; ...
this is fine and it works, but it feels kinda bad? is there an intended way to do this?You can create a parsing loop like this:
(let [rdr (sci/reader f)]
(loop []
(let [form (sci/parse-next ctx rdr)]
(when (not= ::sci/eof form)
(sci/eval-form form)
(recur))))
something like that