Fork me on GitHub
#babashka
<
2020-04-14
>
hobosarefriends07:04:02

> I'm confused by the Requirements section of the README. Is the author being cheeky or do they really not know if the tool requires a JVM?

hobosarefriends07:04:26

Heh... little does he know how stupid I really am, because I'm really not sure.

borkdude07:04:27

Maybe you can explain that you are using https://github.com/taylorwood/clj.native-image (which does require a JVM because it runs using Clojure)

hobosarefriends07:04:28

oh right.. at some point I shoud've mentioned that..

borkdude10:04:26

It's also being mentioned here: https://www.therepl.net/95/

hobosarefriends10:04:20

There's a lot more clojure "news" places than I realized

borkdude10:04:32

> I've been playing with the idea of creating a leanpub book on #clojure shell scripting with #babashka. Would it be better to create a book, or a course? And what would you like to see in it? For now it's only collecting ideas. https://twitter.com/borkdude/status/1250003608529186817

yonatanel10:04:52

I’m wondering about the performance of repeatedly running a function that was defined in sci. Will it be interpreted every time? Is it a good idea to first evaluate in sci, and if it passes, use the less safe clojure.core/load-string on the same string that already passed the safety check (to get a standard fn object)?

borkdude10:04:25

@yonatanel If performance is an issue, then yes, that's a viable option.

borkdude10:04:49

To be clear: the code analysis only happens once, but the returned function will be something that invokes the interpreter every time you run it which comes with some overhead, which especially becomes noticeable in large loops. But for most DSLs I don't expect this to be a noticeable issue, it really depends on your context.

borkdude10:04:42

TIL: clojure.core/load-string. 🙂 I thought one always had to do eval + read-string

yonatanel10:04:54

@borkdude I want to allow users to configure a transformation of a java object which I run just before handing them that object. It means they get the object as as parameter. I already made the type hint and instance method work, but examining the source code I saw it will repeatedly use reflection.

borkdude10:04:40

yes, sci uses reflection for Java interop, so if that's a performance issue, you can delegate to clojure.core/load-string

borkdude10:04:21

the reason we're using reflection is that sci is an interpreter and not a compiler (although there might be some optimizations possible)

borkdude11:04:04

@yonatanel Btw, if you pass sci a function from the outside where this interop is happening, then you don't pay the cost of interpretation, that is executed as is

borkdude11:04:40

e.g.:

(eval-string "(f \"foo\")" {:namespaces {'user {'f #(.getBytes ^String %)}}})

yonatanel11:04:33

@borkdude I’ll have to test the performance of interpreting it in high load, as I’m getting from the user a function that I’ll invoke over and over.

(eval-string "(fn [x] (f x))" {:namespaces {'user {'f #(.getBytes ^String %)}}})

yonatanel11:04:18

Metosin use it and they are very concerned about performance, so maybe it’s great

borkdude11:04:19

in malli it is optional to use it. it used for serialisable schemas that you can also run both a browser and a backend. when you serialize a schema and send it to the front-end, predicates will be evaluated by sci. on the server you can also use sci, but when you trust the schema, you can also use clojure.core/eval or load-string for better performance, like you suggested

yonatanel13:04:42

I ran some crude benchmarks with criterium. Mean times were sci 4.5µs sci with predefined fns: 3µs load-string: 6ns

borkdude13:04:29

does that make a difference in the grand scheme of things though for your application?

yonatanel14:04:26

It’s complicated, but probably not

yonatanel14:04:02

Wait, it will be very significant theoretically. I’ll need to actually run it to make sure.

jstuartmilne12:04:49

i was looking for an example to make a call like

jstuartmilne12:04:24

(shell/sh "ls") but how do i add the linux pipe after that?

borkdude12:04:43

head as in take 10?

borkdude12:04:42

from bash you can do:

$ ls | bb -io '(take 10 *input*)'
from within bb:
bb '(as-> (shell/sh "ls") $ (:out $) (str/split $ #"\n") (take 10 $))'

jstuartmilne12:04:30

cool yeah i was looking for the second option

jstuartmilne13:04:26

my intent is to pipe the yes command

jstuartmilne13:04:42

i have a script that requires me to type yes

jstuartmilne13:04:04

yes | thescript

borkdude13:04:19

so the output of the process can be infinite?

jstuartmilne13:04:45

the output of thescript yeah it can be really really long

borkdude13:04:10

no, I mean, yes prints yes indefinitely. so using shell/sh doesn't work for that, it won't finish reading

borkdude13:04:29

in that case it's better to use ProcessBuilder.

borkdude13:04:13

@jstuartmilne small example:

$ bb '(let [pb (ProcessBuilder. ["yes"]) p (.start pb) out (.getInputStream p)] (take 10 (line-seq (io/reader out))))'
("y" "y" "y" "y" "y" "y" "y" "y" "y" "y")

jstuartmilne13:04:32

interesting. will try that out. thanks

borkdude13:04:37

it's a bit more verbose, but give you the power of redirecting streams from one process to another as well

borkdude21:04:44

Meanwhile I've added a couple of Java classes which now enable you to run this code: https://github.com/statsd/statsd/blob/master/examples/statsd.clj (see discussion in #graalvm)

nate21:04:25

my latest usage of yaml in clojure (to assist in converting my blog from octopress to hugo) runs flawlessly in the snapshot release

borkdude21:04:30

that's good to hear

ddouglass21:04:05

things look good here, aside from some stylistic differences in how snakeyaml thinks things should look 😛