Fork me on GitHub
#babashka
<
2019-12-18
>
oskarkv09:12:36

No letfn? 😞

borkdude09:12:14

@oskarkv It's simply not implemented yet, I'll make an issue

oskarkv11:12:17

(defmacro letfn [bindings & body]
  `(let ~(vec (mapcat (juxt first #(cons 'fn %)) bindings))
     ~@body))
I think this works, btw.

borkdude11:12:01

The point of letfn is not only syntactic sugar but also being able to use a function before it is bound in the key binding

oskarkv11:12:47

Oh, didn't think about that.

borkdude10:12:16

user=> (import '[java.time LocalDate])
nil
user=> (def d1 (LocalDate/parse "2019-11-11"))
#'user/d1
user=> (def d2 (LocalDate/parse "2019-11-12"))
#'user/d2
user=> (.isBefore d2 d1)
false
(in the java-time branch). What classes are important to add beyond the ones listed here in the class/enum/exception summary? https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

borkdude10:12:10

Hmm, adding these classes to the reflection.config adds about 7 MB (binary goes up from 30 MB to 37MB), is it worth it?

oskarkv11:12:46

Is there any math lib or something, with pow etc?

borkdude12:12:19

Not yet, but adding java.lang.Math seems like a no brainer

borkdude12:12:03

what OS are you on?

oskarkv12:12:25

Linux Mint

borkdude12:12:16

Now also merged this to master

borkdude16:12:27

Babashka, a native Clojure scripting tool, v0.0.43: Support for java.time.*, java.lang.Math, java.util.Base64 and java.lang.ProcessBuilder. https://github.com/borkdude/babashka/releases/tag/v0.0.43

borkdude16:12:01

@nate I guess this covers java.time well enough. People can now build their own babashka time libraries on top of the raw Java classes

sogaiu16:12:08

ghadi was saying something in one of his talks about how some of the clojure wrappers for java.time had some "issues" (sorry, paraphrasing), so may be this approach is a good one to start with.

borkdude16:12:41

the java-time one seems needlessly complex to me

4
sogaiu16:12:17

btw, bb recently seems to require java 8 to compile. i was getting away with java 11 up to not-too-long ago 🙂

sogaiu16:12:34

at any rate, the latest commit builds here and all tests pass (with my usual tweak)

borkdude16:12:58

I think it's because of the unix-named classes which got renamed to jdk.internal.something.something

borkdude16:12:12

you might give that a try.

borkdude16:12:41

- Change the unix-named classes in babashka.impl.classes.clj to their JDK 11 equivalents

borkdude16:12:45

- Run lein with-profiles +reflection

borkdude16:12:49

- Then run script/compile

sogaiu16:12:50

for reference, the error is:

Compiling babashka.impl.classes
Syntax error compiling at (babashka/impl/classes.clj:112:16).
Syntax error (ClassNotFoundException) compiling at (babashka/impl/classes.clj:112:16).
java.lang.UNIXProcess$ProcessPipeOutputStream

Full report at:
/tmp/clojure-929038568194110145.edn
Compilation failed: Subprocess failed
so that supports what you are saying i guess.

sogaiu16:12:09

thanks for the hints. i'll take a look in a bit.

borkdude16:12:34

if you get that working, it's useful to add that info to the JDK 11 issue

4
sogaiu18:12:04

@borkdude it seems like just removing the things that have unix in their name works

borkdude18:12:22

removing, but that breaks reflective access

sogaiu18:12:54

ok, i didn't have much luck tracking down new names for relevant classes

sogaiu18:12:13

i guess there are no tests to check reflection for the unix things then?

sogaiu18:12:44

fwiw, the lein command i tried was:

lein do clean, with-profiles +reflection test

sogaiu18:12:48

may be i got that wrong?

borkdude18:12:36

you first have to re-generate the json file with lein with-profiles +reflection run

borkdude18:12:47

then script/compile and then run the tests

borkdude18:12:52

with just lein test

sogaiu18:12:54

ah i see -- your instructions lacked the string "run" so i guessed wrong 🙂

sogaiu18:12:06

np -- am trying now 🙂

sogaiu18:12:31

i have worked hard to forget leiningen usage 😉

sogaiu18:12:59

all tests (tried both script/test and lein test -- former includes latter i presume) pass

sogaiu18:12:12

is it the case that the unix-related classes were actually renamed -- not just subsumed into something else?

borkdude18:12:49

could be. in that case we can just delete them from the config I guess

sogaiu18:12:28

thanks for the test

sogaiu18:12:53

$ ./bb examples/process_builder.clj 
No matching method getOutputStream found taking 0 args for class java.lang.UNIXProcess [at line 11, column 20]

sogaiu18:12:10

so the class still seems to be there?

sogaiu18:12:38

if i add java.lang.UnixProcess back in to classes.clj and run the lein command, i get:

$ lein do clean, with-profiles +reflection run
Syntax error (ClassNotFoundException) compiling at (babashka/impl/classes.clj:110:16).
java.lang.UnixProcess

Full report at:
/tmp/clojure-15381430602635576939.edn
Error encountered performing task 'run' with profile(s): 'base,system,user,provided,dev,reflection'
Suppressed exit

sogaiu18:12:49

i type-hinted proc in the example script with java.lang.Process and that seems to work

sogaiu18:12:10

at least via lein -- am compiling to try via native-image

borkdude19:12:07

are you sure you used jdk11 in both lein (script/compile the jar step) + graal (script/compile the native-image step)?

sogaiu19:12:49

no 🙂 i think i didn't. good point. will retry.

borkdude19:12:53

to be sure just set JAVA_HOME to the Graal JVM

sogaiu19:12:45

my setup doesn't use JAVA_HOME usually -- what code will make use of that?

sogaiu19:12:05

i added --report-unsupoorted-elements-at-runtime to get the compilation to complete. now the error i get at runtime for the process builder script is:

$ ./bb examples/process_builder.clj 
Invoke with MethodHandle argument could not be reduced to at most a single call: java.lang.invoke.Invokers$Holder.invoke_MT(Object, Object, Object, Object)

borkdude19:12:40

I think lein respects JAVA_HOME, but I'm not sure

borkdude19:12:15

yeah, I think you're running into the Reflector.java issue now

borkdude19:12:22

use --verbose

sogaiu19:12:42

--verbose is already in the compile script on a side note, there are some options with = that don't have double quotes around them -- should i submit a pr for that?

borkdude19:12:56

is that problematic?

borkdude19:12:15

if --verbose is already there, the stacktrace probably points to Reflector.java

borkdude19:12:25

clojure.lang.Reflector that is

sogaiu19:12:57

(i don't know if you remember, but we are warned by native-image [whether we have quote them or not] that they might be problematic)

sogaiu19:12:30

regarding the "could not be reduced" message, what i pasted is all that i got, btw

borkdude19:12:59

./bb --verbose examples/process_builder.clj 

sogaiu19:12:00

i'll remove the report at runtime and get more errors from the compilation

sogaiu19:12:12

i misunderstood which verbose 🙂

sogaiu19:12:14

i see the reflector

borkdude19:12:36

yeah, that's an issue that has to be fixed first if we're moving to jdk 11, it's already documented in the issue

borkdude19:12:56

graal doesn't play well with the dynamic usage of resolving a JDK 11 method in that class

borkdude20:12:22

I was thinking of releasing a small lib which copies the code from Reflector.java and removes the JDK8 reference and make the code for JDK 11 more static

borkdude20:12:42

and call it whatever/reflector-jdk11 or something

sogaiu20:12:03

haven't looked at Reflector.java yet -- i guess i'll take a look

borkdude20:12:43

we can also just incorporate it directly in babashka I guess and compile it with lein (I think it's a good choice for graal projects, it can do all the stuff you need)

sogaiu20:12:42

perhaps something relevant can be put in babashka initially and if it proves useful factored out later?

borkdude20:12:49

Next version of babashka will have letfn (it's already on master) (cc @oskarkv)