sci

https://github.com/babashka/SCI - also see #babashka and #nbb
Patrick Farwick 2020-06-30T05:55:31.076700Z

Hello Use case: I am trying to load a file that has a few functions that will add/remove/change data to a map. I am having some issues getting sci to load the file because I would like to use specter to navigate that map. The file loads in the load-fn function but when calling sci/eval-string with the {:load-fn load-fn} argument I get an error of

Caused by java.lang.Exception
   Could not require com.rpl.specter.
I tried to not include the library and use a binding of something like select to sr/select but from my understanding that works in the string itself but not the functions being slurped as source. I could post the couple of errors I ran into while trying a few different things here but didn't feel it was totally necessary yet. Am I missing something? Are there clever ways around this issue?

borkdude 2020-06-30T07:43:36.077500Z

@patrick.farwick The issue is that your code probably somewhere does (require '[com.rpl.specter]) and sci tries to find that namespace but it can't find it in the options you gave it.

borkdude 2020-06-30T07:44:54.078400Z

@patrick.farwick If you want this to work you'll have to provide those functions with {:namespaces {'com.rpl.specter {'select select}}}

borkdude 2020-06-30T07:45:13.078700Z

:bindings is just a shorthand for {:namespaces {'user ...}}

lread 2020-06-30T15:01:44.081400Z

Iโ€™m still having fun playing with sci as a way to run rewrite-cljc tests over a natively compiled rewrite-cljc lib. Iโ€™ve had some small successes, but am now wondering if/how this will work for parts of the rewrite-cljc API that are macros.

borkdude 2020-06-30T15:03:11.081600Z

sci can do macros ๐Ÿ™‚

borkdude 2020-06-30T15:04:33.083200Z

@lee you can try (sci.core/copy-var 'some-macro rewrite-clj/some-macro (sci.core/create-ns 'some-ns nil)) https://borkdude.github.io/sci/doc/codox/sci.core.html#var-copy-var

lread 2020-06-30T15:05:53.084400Z

Oh. Ok! Thanks for the pointer, I shall give it a try!

Patrick Farwick 2020-06-30T15:26:05.086300Z

Hey @borkdude, I appreciate the help (I am pretty positive you answered my github actions / circleci question as well ๐Ÿ™‚ ) Would you expect

(sci/eval-string "(require '[com.rpl.specter]) (select [:a] {:a 1 :b 2})" {:namespaces {'com.rpl.specter {'select select}}})
to work? I get the error
CompilerException java.lang.RuntimeException: Unable to resolve symbol: select in this context, compiling:
`

Patrick Farwick 2020-06-30T15:26:34.086600Z

I wasn't completely done typing that but slack decided I was ๐Ÿ˜

borkdude 2020-06-30T15:29:25.088600Z

if you get a compiler exception, then it's happening before sci even sees it

borkdude 2020-06-30T15:29:35.089100Z

so a regular Clojure error in your program probably

Patrick Farwick 2020-06-30T15:29:59.089800Z

so my thought process after that was, okay, maybe even in the namespaces section it still needed {'select sr/select} because specter is also included in the file I was calling this from, but get the error:

CompilerException java.lang.RuntimeException: Can't take value of a macro: #'com.rpl.specter/select, compiling:

borkdude 2020-06-30T15:30:27.090200Z

@patrick.farwick See the comment I just made to lread: try sci.core/copy-var

Patrick Farwick 2020-06-30T15:31:26.090400Z

Okay let me try that

lread 2020-06-30T16:05:57.092500Z

Success with copy-var on macro, thanks @borkdude! Although I had to copy from the original macro and not the potemkin copy. Iโ€™ll dig into why thatโ€™s the case later.

Patrick Farwick 2020-06-30T16:20:29.093Z

good to hear! I am still struggling a bit to get this to work but I think some of the nuances around this are alluding me

Patrick Farwick 2020-06-30T17:11:24.099Z

Like this kind of works:

(sci/eval-string "(require '[edit :as e]) (e/select [:a] {:a 1 :b 2}))" {:namespaces {'edit {'select (sci/copy-var sr/select (sci/create-ns 'edit nil))}}})
in the sense that it seems to be passing specters select function to the edit namespace in the eval string, but then looking at specters select function it is immediately calling compiled-select* so then I get this error:
ExceptionInfo Could not resolve symbol: com.rpl.specter.impl/compiled-select* [at line , column ]  clojure.core/ex-info (core.clj:4739)
which does make sense if I am not able to include all of specter into sci? Is there a more general way to pull in a whole library? It seems as if calling {:namespaces {'com.rpl.specter {...}}} is more designed for passing specific functions from a library Maybe I am thinking about this problem the wrong way. Effectively I just want the functions in this edit.clj file. I think it would be fine running them in the core namespace if there was a way to load the functions into the ns, rather than trying to load the file and pass libraries in order to run the functions in sci.

borkdude 2020-06-30T17:12:25.099700Z

@patrick.farwick A macro is simply a function transforming an s-expression into another s-expression. If the resulting s-expression calls compiled-select* then you'll also need to include that

borkdude 2020-06-30T17:20:22.100400Z

@patrick.farwick Maybe it helps if you include select as a function? (fn [x] (select x))

borkdude 2020-06-30T17:20:48.101Z

I'm not familiar with that API, but if you do it like that, the expansion happens outside of sci. However, select won't be a macro anymore

Patrick Farwick 2020-06-30T18:02:26.102700Z

Hmm. I see what you are saying about the macro / s-expression piece. I am not totally sure what you mean by including select as a function. There isnt a particular need for select to be a macro. I just thought it was the only way to get specter's select into the sci eval string

borkdude 2020-06-30T18:04:27.103100Z

What I mean is, you can try to lift the macro in a function, like in:

user=> (map #(when % %) [nil false 2 3 4])
(nil nil 2 3 4)

borkdude 2020-06-30T18:04:38.103400Z

whereas (map when ...) doesn't work

borkdude 2020-06-30T20:04:15.104200Z

@patrick.farwick You might be able to do something with ns-publics and copy-var

Patrick Farwick 2020-06-30T20:17:39.107100Z

Yeah, I was kind of thinking about that. So maybe more of a #beginners question (but to be fair I am kind of a beginner ๐Ÿ™‚ ), the functionality of sci is to contain the code that is being run outside of your core program right? I was toying around with just (load-file "edits.clj") into (vals (ns-publics 'edit)) and that seemed to get me the functions that I was looking for. I mean this whole process kind of revolves around RCE but maybe sci contains some of it? I do really appreciate the time and effort you put into helping.

borkdude 2020-06-30T20:18:25.107600Z

What's RCE?

Patrick Farwick 2020-06-30T20:18:37.107800Z

remote code execution

Patrick Farwick 2020-06-30T20:20:15.108400Z

which, it is an internal tool pulling from a file in a location i expect, but i was thinking more of "good software engineering practices"

borkdude 2020-06-30T20:22:34.109400Z

I'm not sure what exactly you are looking for, but the principle around which sci is built: it doesn't execute anything other than you give it, unless it's a pure function from clojure core which doesn't have noticable effects on the outside world.

borkdude 2020-06-30T20:22:58.109900Z

So if you want to make it dangerous, you can, but by default it should be relatively harmless to execute random code

Patrick Farwick 2020-06-30T20:25:09.110600Z

Yes. exactly. that makes sense.

borkdude 2020-06-30T20:25:10.110700Z

For inspiration you can also look at the other projects that are using sci. The "biggest" one is probably babashka.

borkdude 2020-06-30T20:27:09.111300Z

These projects are listed in the README of sci

Patrick Farwick 2020-06-30T20:32:41.111900Z

Yeah, I was looking through a few of them last night along with just searching for projects that included sci across github but was a bit stuck still

Patrick Farwick 2020-06-30T20:37:41.112800Z

I think my trouble has to do with the fact the "dangerous" piece i need to import is effectively a whole library.

borkdude 2020-06-30T20:56:26.113300Z

@patrick.farwick babashka has imported several whole libraries

borkdude 2020-06-30T20:56:49.113500Z

so has bootleg, spire.

borkdude 2020-06-30T20:57:05.113900Z

it takes work, but doable.

Patrick Farwick 2020-06-30T21:18:19.114200Z

Okay, let me check again and try to understand what is going on better

Patrick Farwick 2020-06-30T21:49:53.115900Z

Okay, Well I think i found the couple of examples. I am trying to wrap my head around them in order to give it another try lol