Fork me on GitHub
#babashka
<
2021-05-07
>
solf02:05:42

I’m using a M1 Air and installed bb through homebrew. I didn’t even notice it wasn’t native 😅

plexus10:05:34

Any idea what this error means exactly?

(require 'lambdaisland.uri)
java.lang.IllegalArgumentException: No implementation of method: :getName of protocol: #'sci.impl.vars/HasName found for class: nil [at /home/arne/github/lambdaisland/uri/src/lambdaisland/uri.cljc:12:1]

borkdude10:05:33

@plexus Yes, defrecord in sci currently has the limitation that you cannot implement Java interfaces on it, only Clojure protocols

borkdude10:05:48

The error message could be more informative though

plexus10:05:55

I see, I guess that makes sense

plexus10:05:29

what a shame, I was hoping lambdaisland/uri would "just work" since it's largely pure clojure

plexus10:05:53

looking at that code I do wonder why I'm implementing invoke 😅 , that should be default record behavior... and I guess I can also just define a print handler instead of implementing toString

borkdude10:05:25

@plexus you could use :bb reader conditionals to support the subset of Clojure that sci supports

plexus10:05:58

yeah that's what I was thinking, I think there's a way to do the same stuff that would be simpler and more interoperable anyway

borkdude10:05:15

The rules for this: the :clj branch will be taken, unless there is a :bb branch preceding it

borkdude10:05:46

I was running into the same issue with a parser combinator library which implemented Comparable on a defrecord. That was the only change I had to make to make it compatible with bb. I can in theory support this, but you can only implement one Java interface at a time, so if you try to do two, like in your example, you're already out again.

plexus10:05:10

the second one is overriding a method on a base class, I guess the same stuff applies?

borkdude10:05:43

yeah, it's tricky when it comes to implementing Java stuff. I can "emulate" most stuff but I can't really trick the Java type system.

borkdude10:05:59

I had a hack for reify before which went like this: at compile time, I created multiple reified objects that implemented all subsets of all supported interfaces. At runtime I would choose the most fitting type which would then dispatch to the interpreted implementations. But this didn't work out since you can get a combinatorial explosion of types, e.g. when you have 100 interfaces to support, you can't really do it anymore, since it generates such a huge list. The other approach I tried was: generate one reify object which implements all supported interfaces. But this didn't work out with instance? checks, since it would return true for a lot of stuff you would not expect it to.

borkdude10:05:04

So right now you can use reify with at most one Java interface + any combination of protocols, for this reason. I could extend that approach to defrecord.

borkdude11:05:01

Cool library to show "status lines". You can hook this up to your tasks. https://github.com/lread/status-line