Fork me on GitHub
#babashka
<
2020-01-03
>
Nate Sutton00:01:39

are defprotocol and deftype and reify likely to land in babashka at any point?

borkdude00:01:36

multi-methods maybe yes, defprotocol, deftype and reify probably not. Not because I don't want to, but because that's probably not possible

borkdude00:01:16

I'm working on a port of spec right now which can be interpreted by babashka which just uses maps instead of protocols

Nate Sutton00:01:10

it's tricky when trying to satisfy java interfaces

Nate Sutton00:01:26

I think I'll need to make a java class and compile it to a jar for use in babashka

borkdude00:01:13

maybe there's a way to avoid using those interfaces?

borkdude00:01:29

gotta go sleep now.. bye!

Nate Sutton05:01:10

hmmm I'm not sure how to handle this

Nate Sutton05:01:35

I need sun.nio.fs.MacOSXFileSystem so I can run supportedFileAttributeViews on the filesystem

Nate Sutton05:01:49

but I can't also add the filesystems for other platforms, it seems

Nate Sutton05:01:36

well, not if I want it to compile on macos

Nate Sutton05:01:01

and I'm betting that adding sun.nio.fs.MacOSXFileSystem to default-classes will break builds for linux and windows

Nate Sutton05:01:41

I guess I need to only add some classes if they're available

Nate Sutton05:01:14

without the fs added:

=> (.supportedFileAttributeViews (java.nio.file.FileSystems/getDefault))
No matching method supportedFileAttributeViews found taking 0 args for class sun.nio.fs.MacOSXFileSystem [at /Users/nsutton/Code/nate.babashka.fs/script/repl.bb, line 1, column 1]

Nate Sutton05:01:24

with the fs added:

=> (.supportedFileAttributeViews (java.nio.file.FileSystems/getDefault))
#{"owner" "basic" "posix" "unix"}

Nate Sutton05:01:20

which is then useful for readAttributes because I can query for specific things using (Files/readAttributes path "posix:*" ... )

Nate Sutton05:01:53

if I try to add the filesystems as optional classes like this

Nate Sutton05:01:14

then it's missing from the reflection.json

Nate Sutton05:01:38

but if I add the optional classes to reflection.json then reflection.json differs based on which platform the file is generated on

Nate Sutton05:01:22

which I guess seems fine to me but right now it's checked into git and so it would always be changing based on the developer

Nate Sutton06:01:49

I think the right move is to remove the reflection.json from git and requiring the build servers to generate their own for their respective platforms

Nate Sutton06:01:11

but I'd like to know what you think tomorrow, b*rkdude

borkdude07:01:26

@nate_clojurians Ah, that's interesting. That might also help the Windows build in that regard

borkdude08:01:17

So in classes.clj there should be a conditional based on the operating system

borkdude08:01:34

PR welcome!

borkdude12:01:26

@nate_clojurians Maybe this approach could work:

user=> (try (Class/forName "java.lang.Exception") (catch Exception _))
java.lang.Exception
user=> (try (Class/forName "java.lang.windows.FooBar") (catch Exception _))
nil

borkdude12:01:52

not sure how graalvm handles that, but worth a try I guess

borkdude12:01:53

There are docs about this here: https://github.com/oracle/graal/blob/master/substratevm/REFLECTION.md I'm not sure what will happen if you put those calls at the top-level (which is preferred, because then it's all done at compilation time)

borkdude12:01:38

Alternatively we can try to conditionally load an OS-specific namespace by inspecting (System/getProperty "os.name")

borkdude12:01:56

On my mac that resolves to "Mac OS X"

borkdude12:01:59

maybe the second approach is less hacky

borkdude12:01:10

and also less sensitive to typos

Nate Sutton13:01:56

the second being detect the OS name and then load with Class/forName?

Nate Sutton13:01:21

that seems fine to me and gets around the reflection.json issue

borkdude13:01:06

no, the first approach is Class/forName

borkdude13:01:07

the second approach is requiring a namespace depending on the OS

borkdude13:01:12

which only contains OS-specific classes

borkdude13:01:22

and you merge that into the map in classes.clj

borkdude13:01:57

which will then generate the reflection.json after calling script/compile

Nate Sutton13:01:31

should reflection.json be in git anymore, then? it'll change based on which platform is used to compile

Nate Sutton13:01:57

ok, cool, this is doable

Nate Sutton13:01:54

and you're right, it's less vulnerable to typos

borkdude13:01:21

another (or combined) approach is to create the OS specific classes namespace also using a script

borkdude13:01:03

that will be less confusing to graalvm analysis probably

borkdude13:01:33

but the second approach may already work fine

Nate Sutton13:01:16

I'll give it a try in like 30m and see what happens :)

Nate Sutton14:01:35

ok, a bit more than 30m, but I'm here now

Nate Sutton15:01:32

I'm trying this and it's failing pretty hard:

Nate Sutton15:01:09

$ ./script/compile
Syntax error (ClassNotFoundException) compiling at (babashka/impl/classes.clj:17:5).
babashka.impl.classes.windows

Nate Sutton15:01:16

if I do refers then clj-kondo gets upset that I'm not using the namespaces I'm requiring

borkdude15:01:52

what is on line 17?

borkdude15:01:22

I think you can use (resolve 'babashka.impl.classes.windows/os-classes)

borkdude15:01:43

or maybe even requiring-resolve

borkdude15:01:55

but that's pretty new

Nate Sutton15:01:25

17 is the require

Nate Sutton15:01:36

do (require '[babashka.impl.classes.windows])

borkdude15:01:40

user=> (case os :mac (requiring-resolve 'clojure.string/join))
#'clojure.string/join

borkdude15:01:39

ok well, what will work in any case is generating the babashka.impl.classes.os_specific_classes.clj file using a script

borkdude15:01:47

and then just require that after it has been generated

Nate Sutton15:01:09

ahhh yeah that would work

Nate Sutton15:01:23

I'd like to play with it a little more, if that's ok?

borkdude17:01:10

> The fact that I can make libraries that work for both babashka and jvm clojure is a huge win. Nicely put. That got me thinking. Maybe we should be having a babashka.http(.client) + babashka.test + babashka.spec.alpha library that you can just use from the JVM and as a built-in in babashka. This would take away the need to include them as libraries on the classpath when using bb, while still being able to run them with the JVM if needed?

borkdude17:01:30

Kind of what @sogaiu was hinting at earlier, but now also with the external JVM possibility

Nate Sutton17:01:36

I was hoping it would go that way but didn't want to push 🙂

Nate Sutton17:01:55

a stdlib that's usable elsewhere

Nate Sutton17:01:33

I started building this fs library with something like that in mind

Nate Sutton17:01:01

nate.babashka.fs right now but easy to make it just babashka.fs, if that's something that someone would want in the stdlib

borkdude17:01:19

yeah, it's good to eval these libs for a while and eventually we can incorporate it

Nate Sutton17:01:39

I'm sure my implementation is fairly naive right now and could be optimized

borkdude17:01:04

the clj-http(-lite) lib has been around for ages, so that would be a good starting point maybe

Nate Sutton17:01:19

I'd definitely agree with that

borkdude17:01:41

then I could also remove some gnarly classes from the reflection config

borkdude17:01:25

and we can always bolt on the async http stuff later in the babashka.http(.client) lib

borkdude17:01:41

maybe calling the lib babashka.http is best, so we can also add an http server there later

borkdude17:01:59

or just have two different libs

borkdude17:01:04

aaaargh, options

Nate Sutton17:01:54

babashka.http.client sounds good to me 🙂

Nate Sutton17:01:11

you can stick stuff in babashka.http that's shared between client and server then

borkdude17:01:44

I mean, the lib could have two namespaces: babashka.http.client and babashka.http.server, but they could also be two separate libs. maybe it doesn't matter

borkdude17:01:06

or maybe there could just be one library babashka.stdlib which has all of these namespaces

Nate Sutton17:01:24

babashka.core 🙂

borkdude17:01:47

maybe that's not so nice for people who want to use small libs on the JVM

borkdude17:01:57

ok, I'll think about it. dinner time

borkdude18:01:56

Hmm, if clj-http-lite becomes babashka.http.client, should we also rebrand cheshire.core to babashka.json? Or maybe we should just map babashka.http.client to clj-http.client?

borkdude18:01:47

But then the code isn't directly portable anymore. Something to think about

Nate Sutton19:01:17

I like the rebranding because you could change the underlying implementation if you need to

Nate Sutton19:01:26

replace it wholesale if you want even

Nate Sutton19:01:47

whereas naming it "cheshire" implies that it's based on that

borkdude19:01:37

so cheshire.core/parsed-seq would become babashka.json/parsed-seq? that would still mean that we would support everything currently in cheshire

borkdude19:01:43

(as people are used to a certain API and not to re-invent the wheel for everything)

borkdude19:01:53

(which is a looot of work)

Nate Sutton19:01:29

yep, but you could expand it or change it if you want having a babashka chesire vs a core cheshire

borkdude19:01:00

and rebranding clojure.tools.cli and clojure.data.csv etc... dunno about that

Nate Sutton19:01:10

hmmm yeah that's a good point

Nate Sutton19:01:43

you're replacing spec with a babashka version

Nate Sutton19:01:56

but that's not really a rebranding I guess

Nate Sutton19:01:00

that's new just with the same api

borkdude19:01:10

for now, because it's a subset of spec to not surprise people that not everything works

borkdude19:01:28

it's a working title

Nate Sutton19:01:40

the goal is to have 1:1 feature-wise with it?

borkdude19:01:05

probably not the generator stuff and the fdef stuff also not maybe, but maybe it's possible. we'll have to see

borkdude19:01:36

it seems to me most people are going to use it for validation / conforming in scripts, not really for instrumenting

Nate Sutton19:01:08

maybe the line could be that if it's a third party tool (read: not clojure.*) that it gets renamed?

borkdude19:01:32

I like that idea

borkdude19:01:56

there is also clojure.data.json btw, but cheshire seems more popular. I've never used the former

Nate Sutton19:01:17

I didn't even know that it existed ...

borkdude19:01:47

go figure 😉

Nate Sutton19:01:29

and also works in progress get a new name until they reach sufficient feature parity?

borkdude19:01:04

yeah, spartan.* I guess

borkdude19:01:37

not carved in stone

borkdude19:01:39

any name works

Nate Sutton19:01:55

can't wait for babashka.frankenweasel.fs to land

Nate Sutton19:01:12

gotta run 🙂