sci

https://github.com/babashka/SCI - also see #babashka and #nbb
ikitommi 2020-07-22T17:18:29.328300Z

cool, works.

ikitommi 2020-07-22T17:18:54.328500Z

if one has handle to the original ctx and adds anything to it, it will be visible to all future forks.

borkdude 2020-07-22T17:19:23.328700Z

I don't think so?

ikitommi 2020-07-22T17:19:41.328900Z

(let [ctx (init nil)]
  (eval-string* ctx "(def secret 123)")
  (eval-string* (fork ctx) "{:secret secret}"))
; => {:secret 123}

ikitommi 2020-07-22T17:20:05.329100Z

I guess it’s intentional?

borkdude 2020-07-22T17:20:34.329300Z

yes, the fork is based on the context at the time you forked it

ikitommi 2020-07-22T17:21:18.329600Z

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))))

borkdude 2020-07-22T17:22:26.329800Z

I don't think that's necessary to add any combination of API functions back into the API itself

ikitommi 2020-07-22T17:22:34.330Z

ok

borkdude 2020-07-22T17:23:04.330200Z

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

borkdude 2020-07-22T17:25:00.330400Z

let me try

borkdude 2020-07-22T17:26:27.330600Z

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.

borkdude 2020-07-22T17:27:48.330800Z

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

borkdude 2020-07-22T17:28:12.331Z

So as long as you don't use sci vars in your options (which are mutable like Clojure vars) you are OK

borkdude 2020-07-22T17:29:43.331200Z

Guess that covers the typical malli use case

ikitommi 2020-07-22T19:32:35.331900Z

got the dynaload + preload + sci kinda working, just need kaocha to co-operate.

ikitommi 2020-07-22T19:32:51.332200Z

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))))))

ikitommi 2020-07-22T19:33:33.333100Z

the main-ns creates the evaluator with options and re-uses that.

borkdude 2020-07-22T19:33:49.333500Z

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 πŸ˜‰

borkdude 2020-07-22T19:34:12.333800Z

E.g. the preloads feature only works with clojure, not with clojurescript

ikitommi 2020-07-22T19:34:24.334100Z

😱