Fork me on GitHub
#babashka
<
2020-03-13
>
skuro13:03:49

user=> (.println *err* "test")
No matching method println found taking 1 args for class .PrintWriter [at line 22, column 1]
user=> (class "test")
java.lang.String

skuro13:03:02

but PrintWriter does have println(String)

skuro13:03:34

am I doing some rookie mistake here?

borkdude13:03:00

@skuro this probably works:

(binding [*out* *err*] (println "test"))

skuro13:03:18

seems so indeed

skuro13:03:24

any reason why that's different?

borkdude13:03:55

@skuro I've only included the constructor of PrintWriter for interop: https://github.com/borkdude/babashka/blob/7dc1fab97698ab80d53351a8b4d7f3149790feee/src/babashka/impl/classes.clj#L103 just to save some space 😉

borkdude13:03:16

using binding seemed what most people were doing anyway so I didn't suspect this was needed

skuro13:03:54

fair enough, works for me

skuro13:03:22

not sure it's worth the extra few kb that each bb user will have to waste honestly

jjttjj15:03:57

Is there something im doing wrong here to call methods on js classes? 😅

(sci/eval-string "(.toUpperCase \"a\")"
                 {:classes {'String js/String}})
;;=? "FUNCTION TOUPPERCASE() { [NATIVE CODE] }"

borkdude15:03:19

hah. I think that's a bug in the sci JS interop. it might be nice to fix, but I think @jeroenvandijk was also working on this.

jjttjj15:03:02

cool I can check back in a few days

borkdude15:03:08

this works though:

cljs.user=> (sci/eval-string "(to-upper-case \"a\")" {:bindings {'to-upper-case #(.toUpperCase %)}})
"A"

borkdude15:03:26

@jeroenvandijk did you have a fix for the above issue?

borkdude16:03:46

@jjttjj the JS interop now looks like this:

(if (identical? \- (.charAt method-name 0))
               (aget obj (subs method-name 1))
               (if-let [method (aget obj method-name)]
                 (apply method obj args)
                 (throw (js/Error. (str "Could not find method: " method-name)))))

borkdude16:03:32

maybe for strings that isn't correct

borkdude16:03:04

there are two PRs here, but I lost track of what kind of work was happening in which: https://github.com/borkdude/sci/pulls

jjttjj16:03:31

Ok cool I will definitely take a look a little later and see what I can do

jjttjj16:03:43

Here's another quick possible bug in cljs:

(sci/eval-string "(println 23)(println 55)" {'println println})
;;=>
Error: cljs.core.deref(...).append is not a function [at line 1, column 1]
    at new cljs$core$ExceptionInfo (/js/cljs-runtime/cljs.core.js:37203:10)
    at Function.eval [as cljs$core$IFn$_invoke$arity$3] (/js/cljs-runtime/cljs.c...

jjttjj16:03:14

might be related actually

borkdude16:03:37

that one is kind of expected, because by default sci does not allow println by binding *out* to nothing

borkdude16:03:52

and your options should have something like :bindings around it

borkdude16:03:09

or :namespaces

jjttjj16:03:10

ah! yes that was it

jjttjj19:03:58

is there any way to have a function outside of sci access the full context sci has when that function is called from within eval-str? (sorry still stuck on some weird code walking stuff)

borkdude20:03:34

why do you need this?

jjttjj20:03:45

still trying to get javelin working on cljs

jjttjj20:03:43

don't want you to waste too much time thinking about this haha it's probably a bad idea and/or not possible

jjttjj20:03:20

I have it somewhat working if I hardcode the same args passed to eval-string internally

borkdude20:03:28

I'm trying to figure out if what you want is already supported. So unless you give me your technical requirements and background, I can't help you very much

jjttjj20:03:23

I’m trying to get macros in javelin (https://github.com/hoplon/javelin) working with sci on cljs. Namelly the cell= macro, which does elaborate code walking. I want this so that I can use javelin inside a sci repl ui inside a browser

(def x (cell 1))
(def y (cell= (+ x 2)))
@y  ;;=> 3

(macroexpand-1 '(javelin.core/cell= (+ x 2)))
((javelin.core/formula (fn [gen1] (+ gen1 2))) x) ;;simplified
cell= basically walks the whole form you pass it and extracts all symbols which might be cells, and then extracts them, and puts the rest of the body in a function that is passed to javelin’s formula function, which returns another function to apply to those symbols Macroexpansion must be done on the form you pass cell=, and I belive that’s where the problem is. Then macroexpansion needs to include the outside env, and javelin obviously expects the env that clojurescript macros use (which is different than sci’s &env, or the regular clj macro &env) I basically need to get this working in sci https://github.com/hoplon/javelin/blob/557b51ce14f31c391aefa8a22c8c2aa42db7b269/src/javelin/core.clj#L219 So I beleive the problem line of the file I’m trying to adapt to sci is: https://github.com/hoplon/javelin/blob/557b51ce14f31c391aefa8a22c8c2aa42db7b269/src/javelin/core.clj#L65

borkdude20:03:00

can you reduce this problem to an example where I don't need knowledge of javelin?

jjttjj20:03:16

Yes, will do

borkdude20:03:05

@jjttjj what might help is looking at https://github.com/borkdude/babashka/blob/7dc1fab97698ab80d53351a8b4d7f3149790feee/src/babashka/main.clj#L356 there I first create the ctx because I have some functions that need it, like the REPL

borkdude20:03:48

it is a private API so things might chance, so use it at your own risk. if it works for your kind of problem, we can try make it public

jjttjj20:03:10

oh yeah, I didn't think to use the internal eval-string* even though I was using other internal stuff (lke macroexpand-1), i think with both these I should be able to get it to work

borkdude20:03:02

ok make it work and if it works, please bother making an issue with the stuff you needed from the impl namespaces, so we can make it public and document it

borkdude20:03:48

I also created the sci-ctx once, so if you eval multiple expressions in the REPL you don't need to re-create it every time, which saves like 1 ms on every call because it avoids merging hash-maps (options + defaults) 😉

jjttjj20:03:19

Ok cool will do, my brain is a bit fried from messing with this all day, but will keep you posted and have a better explanation of what's going on when it becomes unfried, thanks again!

borkdude20:03:38

I know the feeling 😉

parrot 1
nate22:03:42

I remember that hato was a something of a non-starter for inclusion in babashka, but what about including HttpClient and WebSocket classes themselves? Too low level to be useful? or are they what was causing the issues?

borkdude22:03:32

unless there are very good reasons to include these classes

Nate Sutton22:03:53

shelling out is great since it mimics what a shell script does, imo

nate22:03:03

yeah, that makes a lot of sense

nate22:03:40

I can't think of a reason for babashka the curl namespace solves the problem appropriately

borkdude22:03:42

there is already HttpUrlConnection in bb btw to support the clj-http-lite library, but maybe eventually, if babashka.curl works out well, we could even remove that (but not without inquiring if anyone still uses it for something).

Nate Sutton22:03:06

I wish tools like curl and similar had options for more machine-friendly output

✔️ 1
Nate Sutton22:03:01

I used to have to parse the output of lftp and other tools in my last job and it's such a pain, particularly if you want progress as things are transferred