Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic vars + copy-ns #768

Closed
galdolber opened this issue Jun 19, 2022 · 2 comments
Closed

Dynamic vars + copy-ns #768

galdolber opened this issue Jun 19, 2022 · 2 comments

Comments

@galdolber
Copy link
Contributor

version

{:sha "75117e6139d0026d4dd035932862134a21c2c41a"}

platform

Mac V.11.2.3

problem

When using sci/copy-ns of a namespace that contains dynamic vars, the dynamic vars are not working in the interpreter.

repro

(ns clojure-ns) (def ^:dynamic *var*)

*** Start a sci runtime with***
(sci/init {:namespaces {'clojure-ns (sci/copy-ns clojure-ns (sci/create-ns 'clojure-ns nil))} :features #{:clj :cljs}})

*** Inside the sci runtime***
(binding [clojure-ns/*var* true] clojure-ns/*var* )

Getting error: Can't dynamically bind non-dynamic var ***

expected behavior

No error

I checked the code under vars.cljc, I think its not possible to do this as the dynamic vars inside the interpreter are managed completely differently, but please let me know if there's a way to do it. What I'm looking for is a way to interop from sci to the clojure(script) code transparently with common dynamic vars.

Sponsor

@borkdude
Copy link
Collaborator

@galdolber I pushed b5b550a now which includes dynamic metadata.

You're right, SCI has its own way of dealing with dynamic vars. It is decoupled from Clojure since any Clojure dialect has a different way of dealing with vars and also because SCI's context is fully isolated from the host: you don't want to have any Clojure vars in there which could cause safety issues.

To deal with this case, what I've done in several projects, including babashka, is wrap functions that need to see the binding from the host:

(ns sci.examples.dynamic-vars
  (:require [sci.core :as sci]))

(def ^:dynamic *items* 10)

(defn foo [] (+ *items* 12))

(def mns (sci/create-ns 'my.namespace nil))

(def items (sci/copy-var *items* mns))

(defn sci-foo []
  (binding [*items* @items]
    (foo)))

(def ctx
  (sci/init {:namespaces
             {'my.namespace {'foo (sci/copy-var sci-foo mns {:name 'foo})
                             '*items* items}}}))

(prn (sci/eval-string* ctx "
(require '[my.namespace :as m])
(binding [m/*items* 1337] (m/foo))"))
;; => 1349

@galdolber
Copy link
Contributor Author

Thanks! that worked!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants