sci

2022-10-12T19:41:24.499469Z

Does using sci from cljs work the same way as from clj? I'm trying to determine if it fits the requirements I have for a project where I need a tiny lisp interpreter. More or less I need to be able to evaluate small lisp expressions with some custom functions injected, but I also need to be able to walk it after macroexpansion and find any usages of what's effectively a new special form prop and extract that information before evaluation. Is that reasonably within reach with sci?

teodorlu 2022-10-12T20:09:00.844849Z

To the best of my understanding, I think that should be possible. At least, I don't know of any reason why it's not possible. A specific example would help :) Here's the sci README on macros: https://github.com/babashka/sci#macros

2022-10-12T20:09:49.859489Z

Yeah, I was reading through this and I can see macros are supported, but I haven't been able to tell if there's any way to get the non-evaluated macroexpanded expression.

2022-10-12T20:09:52.869979Z

Which is a value I need

2022-10-12T20:10:31.803959Z

I don't see anything about macroexpanding in the api markdown file either

phronmophobic 2022-10-12T20:15:37.716679Z

Is there any reason you can't submit the form as (clojure.walk/macroexpand-all (quote ~form)) to get what you need?

phronmophobic 2022-10-12T20:16:16.109219Z

or even:

{:expanded (clojure.walk/macroexpand-all (quote ~form))
  :result ~form}

2022-10-12T20:16:46.466209Z

So you mean like read in the expression, wrap it in a macroexpand all, quote it, and then eval that?

phronmophobic 2022-10-12T20:17:00.087749Z

yea

2022-10-12T20:17:09.330819Z

I guess I could potentially do that.

2022-10-12T20:17:24.024809Z

is that macroexpand all provided by sci?

2022-10-12T20:17:30.712459Z

I don't think I can provide it in cljs

phronmophobic 2022-10-12T20:17:51.604789Z

I tried it in bb

2022-10-12T20:18:05.675229Z

I think this would need nbb

phronmophobic 2022-10-12T20:18:06.186479Z

I'm not sure if that means it also applies to sci in cljs

2022-10-12T20:18:38.330689Z

I'll give it a shot a little later

phronmophobic 2022-10-12T20:18:49.586199Z

I don't have nbb handy, but should be easy to test

2022-10-12T20:20:02.991179Z

Yeah, I'll test it out. If that works, then I think I can use sci as-is. If not, then I might need to look at the inner workings and think about a PR to add a macroexpand to the API.

teodorlu 2022-10-12T20:22:32.740239Z

(require '[sci.core :as sci])

(let [ctx (sci/init {})]
  (sci/eval-form ctx '(do (defmacro lol [y] y)
                          (def x 123)
                          {:x-stuff (* x (lol x))
                           :macro-stuff (macroexpand (quote (lol :abc)))})))
;; => {:x-stuff 15129, :macro-stuff :abc}
Something like this?

2022-10-12T20:23:30.731179Z

yea

borkdude 2022-10-12T20:23:36.818209Z

macroexpand is available inside SCI already

✅ 1
2022-10-12T20:24:07.184199Z

Yeah, it's available from inside, my question was about doing macroexpand instead of eval-form

2022-10-12T20:24:27.642249Z

Which yeah, looks like can be done by just wrapping macroexpand and quote before evaling

borkdude 2022-10-12T20:24:41.085819Z

yeah, that's how I'd do it

borkdude 2022-10-12T20:26:04.965779Z

> I don't have nbb handy npx nbb is all you need :)

teodorlu 2022-10-12T20:26:28.675829Z

(defn macroexpand-in-sci [code]
  (let [ctx (sci/init {})]
    (sci/eval-form ctx
                   `(macroexpand (quote ~code)))))

(macroexpand-in-sci '(when true
                       :abc))
;; => (if true (do :abc))

2022-10-12T20:26:52.057289Z

My issue here is I'm basically writing a bunch of tiny separate sci expressions which need to be able to refer to stuff that's provided outside of the sci context by way of this prop special function but I have to be able to find usages of prop outside the context of sci

2022-10-12T20:27:18.618539Z

although putting some more thought into that I might even need to mess with that a little more because of the potential for constructing symbols at runtime to pass to prop

teodorlu 2022-10-12T20:28:14.988749Z

I'm still not grasping exactly what you're hoping to achieve :)

borkdude 2022-10-12T20:29:39.626629Z

you could also do a walk on the code before you feed it into sci

👍 1
2022-10-12T20:30:05.394909Z

That's what I'd initially thought to do but I need to macroexpand first

2022-10-12T20:30:22.783209Z

This is just one tiny part of a very complex whole that I'm trying to work out a spec for and determine exactly what components need what features. ATM it's looking like sci can do what I need from an interpreter though.

borkdude 2022-10-12T20:30:29.575699Z

ok, so you do first a macroexpand inside SCI, then walk that expression and then eval that expression in SCI :)

2
2022-10-12T20:30:56.930239Z

yup, that's the conclusion we came to! Glad that's confirmed to work. 🙂

2022-10-12T20:05:50.399699Z

It seems like I'd be able to do most of this, but I'm not quite sure with a separate macroexpand step