cool, works.
if one has handle to the original ctx and adds anything to it, it will be visible to all future forks.
I don't think so?
(let [ctx (init nil)]
(eval-string* ctx "(def secret 123)")
(eval-string* (fork ctx) "{:secret secret}"))
; => {:secret 123}
I guess itβs intentional?
yes, the fork is based on the context at the time you forked it
added this to malli, maybe it could be on sci side?
(defn evaluator [options]
(let [ctx (init options)]
(fn eval [s]
(eval-string* (fork ctx) s))))
I don't think that's necessary to add any combination of API functions back into the API itself
ok
There is one edge case, when you add your own vars to the initial context, users may or may not be able to alter-var-root things. I have to think more about this
let me try
So the core vars are OK:
user=> (sci/eval-string* (sci/fork ctx) "(alter-var-root #'clojure.core/inc (constantly dec))")
Execution error (ExceptionInfo) at sci.impl.vars.SciVar/bindRoot (vars.cljc:250).
Built-in var #'clojure.core/clojure.core/inc is read-only.
And this is also OK:
user=> (def ctx (sci/init {:profile :termination-safe :bindings {'x 1}}))
#'user/ctx
user=> (sci/eval-string* (sci/fork ctx) "(alter-var-root #'x (constantly dec))")
Execution error (IllegalArgumentException) at sci.impl.vars/eval448$fn$G (vars.cljc:156).
No implementation of method: :getRawRoot of protocol: #'sci.impl.vars/IVar found for class: java.lang.Long
So as long as you don't use sci vars in your options (which are mutable like Clojure vars) you are OK
Guess that covers the typical malli use case
got the dynaload + preload + sci kinda working, just need kaocha to co-operate.
looks like this atm:
(ns malli.sci
(:require #?(:clj [borkdude.dynaload-clj :refer [dynaload]]
:cljs [borkdude.dynaload-cljs :refer-macros [dynaload]])))
(defn evaluator [options]
(let [eval-string* @(dynaload 'sci.core/eval-string* {:default nil})
init @(dynaload 'sci.core/init {:default nil})
fork @(dynaload 'sci.core/fork {:default nil})]
(if (and eval-string* init fork)
(let [ctx (init options)]
(fn eval [s] (eval-string* (fork ctx) s))))))
the main-ns creates the evaluator with options and re-uses that.
Been there. I tried to fix the malli unit tests that are ran with koacha, but I ran into issues and decided to just write the library π
E.g. the preloads feature only works with clojure, not with clojurescript
π±