sci

2022-04-30T09:04:03.403249Z

I'm not an expert, but I was playing with packaging all of this work up, and tools.build skipped my sha-based sci because it expects me to have a version ... any timeframe on some of these recent changes being included in a release version of sci, @borkdude ?

borkdude 2022-04-30T09:04:47.240399Z

define "packaging up"?

2022-04-30T09:06:05.848739Z

Sorry - I was trying to package this stuff in a jar (using tools.build) (having the following dependency in my deps.edn: org.babashka/sci {:git/url "" :git/sha "fcf7e6067f091fd2cf2843660349e820c4449dd8"}) and I saw a message I'd never seen before:

Skipping coordinate: {:git/url , :git/sha fcf7e6067f091fd2cf2843660349e820c4449dd8, :deps/manifest :deps, :deps/root /Users/pmooser/.gitlibs/libs/org.babashka/sci/fcf7e6067f091fd2cf2843660349e820c4449dd8, :parents #{[]}, :paths [/Users/pmooser/.gitlibs/libs/org.babashka/sci/fcf7e6067f091fd2cf2843660349e820c4449dd8/resources /Users/pmooser/.gitlibs/libs/org.babashka/sci/fcf7e6067f091fd2cf2843660349e820c4449dd8/src]}

2022-04-30T09:06:56.724189Z

And reading the source code of tools.build it appears that it does that if an artifact doesn't have a mvn/version ... so that meant it wasn't clear to me how I was supposed to include (read: depend upon) such an artifact in a build.

borkdude 2022-04-30T09:07:44.304869Z

You mean build an uberjar right? I think tools.build should be able to do that? Ask in #tools-build first maybe

borkdude 2022-04-30T09:08:48.231189Z

I could just release a version, but I think it's better to fix things at their root cause and being able to use SCI as a git dep will be better for quicker iteration

2022-04-30T09:10:30.681349Z

Sure thing. Happy to give that a try. Thanks.

borkdude 2022-04-30T15:33:50.918729Z

Started some work on async eval for CLJS (based on promises). Here are some tests: https://github.com/babashka/sci/blob/promised-eval/test/sci/async_test.cljs

devn 2022-04-30T18:19:22.930529Z

How safe is SCI’s default eval-string (with no additions) for the purposes of running completely untrusted code?

borkdude 2022-04-30T18:22:11.090859Z

@devn Pretty safe, there is no file system access, no Threads. The only unsafe thing is that it might never terminate since it's turing complete

devn 2022-04-30T18:22:14.941429Z

(sci/eval-string "#=(clojure.core/list clojure.core/- #=(clojure.core/+ 1 5) 2 3)") ran, which I guess I was just a bit surprised at

borkdude 2022-04-30T18:23:31.203649Z

interesting, I'm surprised too :)

devn 2022-04-30T18:23:53.965569Z

out of curiosity, does sci expose something like a “safe” read-string?

borkdude 2022-04-30T18:24:27.950709Z

edamame does: https://github.com/borkdude/edamame - this is used in SCI. I think the read-eval thing should probably be turned off by default

borkdude 2022-04-30T18:25:28.984709Z

Hmm:

:all true
:read-eval false

devn 2022-04-30T18:25:34.986299Z

even with read-eval here, it still shouldn’t really matter much with no fs access, etc. — i think?

borkdude 2022-04-30T18:25:42.191989Z

are the default options used. I'll see what will happen. Yes, that's true

borkdude 2022-04-30T18:26:47.346979Z

user=> (e/parse-string "#=(+ 1 2 3)" {:all true})
(read-eval (+ 1 2 3))
user=> (e/parse-string "#=(+ 1 2 3)" {:all true :read-eval false})
Execution error (ExceptionInfo) at edamame.impl.parser/throw-reader (parser.cljc:44).
Read-eval not allowed. Use the `:read-eval` option

devn 2022-04-30T18:27:00.164789Z

since im running like 100k untrusted expressions, i am just dotting my i’s. frankly sci seems safer than when i ran these in clojail. i had little java swing windows popping up on my VM and such. 😄

borkdude 2022-04-30T18:27:12.505809Z

haha

borkdude 2022-04-30T18:30:07.414029Z

Oh I see what happened. Support for *read-eval* got added later and this enabled that option:

user=> (sci/eval-string "(binding [*read-eval* false] (read-string \"#=( 1 2 3)\"))")
Execution error (ExceptionInfo) at sci.impl.parser/throw-eval-read (parser.cljc:87).
EvalReader not allowed when *read-eval* is false.

borkdude 2022-04-30T18:30:36.777919Z

but I can expose sci/read-eval so you can bind that to false

borkdude 2022-04-30T18:36:01.779499Z

@devn fixed on SCI master: *read-eval* defaults to false now and you can do:

(sci/binding [sci/read-eval true] ...)
to enable it

devn 2022-04-30T20:16:33.941919Z

very nice. thank you!

devn 2022-04-30T20:19:12.698899Z

fwiw, i just got it back into a deployed state at http://getclojure.org search is not as good as it once was when i was using elasticsearch with my own custom tokenizer/analyzer combo. certainly a lot of junk sexps in there, but occasionally there’s something interesting

borkdude 2022-04-30T20:24:37.833269Z

awesome! and this is eval-ed using SCI right?

borkdude 2022-04-30T20:25:41.046859Z

lol, yes I can see that here:

(fn [n]
  (let [zeros (vec (repeat n 0))]
    (map #(assoc zeros % 1 (inc %) 1) (range (dec n)))))
#object[sci.impl.fns$fun$arity_1__2260 0x2a5b0042 "sci.impl.fns$fun$arity_1__2260@2a5b0042"]

borkdude 2022-04-30T20:26:50.332449Z

@devn Maybe examples that return functions aren't so interesting to show?

devn 2022-04-30T20:28:04.445199Z

yeah, all of this was eval’d in SCI yeah i tend to agree on examples returning functions. there’s also some pretty clear cases where clojurebot macroexpanded an expression for someone, so you wind up with a giant block of (clojure.core/list (clojure.core/+ (clojure.core/list …)))

devn 2022-04-30T20:29:51.792379Z

the behavior in elasticsearch was “better” insofar as the complexity of the input seemed to correspond to it’s ranking, so page one for a search of comp would yield boring things like (comp comp comp comp comp) , but the last page would have longer examples. im not sure how the ranking is happening here but it’s a little odd

devn 2022-04-30T20:31:57.953529Z

like, i have no idea why this query http://getclojure.org/search?q=%2B%2B%2B%2B%2B&num=0 returns the example (list 1 2)

borkdude 2022-04-30T20:32:47.717479Z

why not use elasticsearch then?

devn 2022-04-30T20:34:07.315719Z

i mean, i don’t know if elasticsearch would be better here on a more recent version. the last time i used it was like 6 major versions ago. i started working on setting it up, but found the docker setup for it to be annoying enough that i figured i’d happy path it on algolia first

devn 2022-04-30T20:34:14.987199Z

so in short: laziness 😄

borkdude 2022-04-30T20:34:31.204829Z

sure :)

devn 2022-04-30T20:35:10.720719Z

and well, i’ve had good experiences with algolia for business-type applications, but this is a weird one because it’s like “no really, i want users to be able to search for .

devn 2022-04-30T20:35:20.947529Z

so a lot of the defaults probably just need to be removed

borkdude 2022-04-30T20:35:53.843059Z

https://grep.app/ does allow you to search for anything, basically like grep

devn 2022-04-30T20:36:14.966569Z

oooo!

borkdude 2022-04-30T20:36:19.634079Z

haven't found out if that's open source - seems not

devn 2022-04-30T20:37:47.069499Z

the original idea was to try and come up with some kind of hoogle-type search for clojure. this is WELL short of that. do you recall crossclj DOT info by any chance? it was around years ago and it was indexing lots of clojure repos and let you click on a function from another lib and hop around like a graph

devn 2022-04-30T20:38:22.634419Z

it’s been dead for awhile, but it was a cool project

borkdude 2022-04-30T20:38:35.975839Z

I've made a hoogle like thing here: https://borkdude.github.io/re-find.web/?args=2%20%5B%3Aa%20%3Ab%20%3Aa%20%3Ab%5D&ret=%5B%3Aa%20%3Aa%5D I remember crossclj - I actually wanted to remake that using clj-kondo analysis output, it contains all the info necessary for that

devn 2022-04-30T20:38:58.787169Z

oh hey, that’s really cool!

borkdude 2022-04-30T20:41:02.653399Z

I wouldn't mind if someone stole my idea of using clj-kondo analysis to re-build cross clj

borkdude 2022-04-30T20:41:11.230029Z

or collaborate on that with someone else

devn 2022-04-30T20:42:23.242159Z

this is less interesting than the spec thing, but https://github.com/Raynes/findfn/blob/master/src/findfn/core.clj wasn’t actually all that bad

borkdude 2022-04-30T20:43:00.730169Z

yeah, that was one of the inspirations as well. I explained in my talk why re-find was better since it excluded non-sensical suggestions like using merge on a number

devn 2022-04-30T20:43:15.623779Z

yeah, that was definitely the brute force attempt

borkdude 2022-04-30T20:43:36.878659Z

but still a very cool project. Raynes made a lot of original things

devn 2022-04-30T20:43:38.518409Z

but it ran pretty fast despite that

devn 2022-04-30T20:44:05.776479Z

yeah, sad he’s not around. hard to believe he was 16 back when he started with clojure

borkdude 2022-04-30T20:44:18.984099Z

he was a badass and also a very nice person

devn 2022-04-30T20:44:39.400639Z

yeah, 100%

borkdude 2022-04-30T20:44:52.919859Z

it seems he passed away so suddently, don't really know any details

devn 2022-04-30T20:46:17.397909Z

i know some folks in the community reached out to his family, but i don’t know any details, and in the end, the result is the same anyway

devn 2022-04-30T20:47:28.237509Z

re-find.web is really neat

devn 2022-04-30T20:56:25.190809Z

continuing the off-topic theme briefly, was pleased to see SCI managed to run this one. wasn’t sure if things in walk would work without explicit inclusion

(clojure.walk/postwalk
  #(if (coll? %) % (str %))
  '((E (C) (F I) F)
     (A A)
     H
     ((G) B)
     ((E G (I (I I A)) H I) (B) (A) C (D (H)))
     (F C C)))

=> (("E" ("C") ("F" "I") "F") ("A" "A") "H" (("G") "B") (("E" "G" ("I" ("I" "I" "A")) "H" "I") ("B") ("A") "C" ("D" ("H"))) ("F" "C" "C"))

devn 2022-04-30T20:58:33.217719Z

there are a lot of examples which would probably run if they were transformed to include the likely ns. plenty of examples of people writing out (postwalk-replace …) unprefixed

borkdude 2022-04-30T21:06:11.753349Z

you can make that work by evaluating a :refer [..] in the same context

borkdude 2022-04-30T21:12:22.727019Z

@devn Can I share http://getclojure.org on Twitter or is it too early?

devn 2022-04-30T21:14:45.175669Z

of course! there is some work to do yet, but contributions, feedback, ideas, etc. all welcome

borkdude 2022-04-30T21:18:49.312939Z

@devn Maybe #announcements too? With the invitation to contribute :)

borkdude 2022-04-30T21:18:59.582239Z

I'll let you do that, if you want to

devn 2022-04-30T21:21:18.850319Z

yeah, will drop a note in there tomorrow night probably. going to add some polish and muck with the search a bit to see if i can get nicer behavior. may also re-run the FULL input set. SCI is markedly faster than I remember clojail being, so i was iterating on just the working examples from the last run which was around clojure 1.5

👍 1
devn 2022-04-30T21:39:21.988989Z

(sci/eval-string "(print \"#=(spit \\\"foo.txt\\\" \\\"hello\\\")\")") Any idea why this fails to evaluate? (Note: I’m still on the version that allows read-eval)

borkdude 2022-04-30T21:41:38.636399Z

In Clojure:

user=> (load-string "(print \"#=(spit \\\"foo.txt\\\" \\\"hello\\\")\")")
#=(spit "foo.txt" "hello")nil

borkdude 2022-04-30T21:42:03.051309Z

I guess using read-eval inside a string does not read-eval

borkdude 2022-04-30T21:42:08.022319Z

since the string is preserved

devn 2022-04-30T21:43:00.772659Z

oh yes, i was mostly interested in seeing if someone could do something nasty like:

(read-string (with-out-str (read-string "#=(print \"#=(spit \\\"foo.txt\\\" \\\"hello\\\")\")")))

devn 2022-04-30T21:43:26.697199Z

because i do read-string on the output value in order to format it

devn 2022-04-30T21:45:44.535679Z

to be more specific, what i was trying to ask is: why does clojure read-string work on this example, but it fails eval-string in sci?

borkdude 2022-04-30T21:47:16.826069Z

what fails exactly? if you type that expression in a clojure REPL vs SCI, what difference do you see? with #babashka I get identical results

devn 2022-04-30T21:48:32.077089Z

ah, my fault was in not binding sci/out

devn 2022-04-30T21:49:15.002909Z

(read-string (:y (with-open [w (StringWriter.)]
                   (sci/binding [sci/out w]
                     {:x (sci/eval-string "#=(clojure.core/print \"#=(spit \\\"foo.txt\\\" \\\"hello\\\")\")")
                      :y (str w)}))))
demonstrates how i can own myself 😄

borkdude 2022-04-30T21:49:30.867429Z

😆