Fork me on GitHub
#clojure
<
2022-12-05
>
arohner13:12:54

Are there any examples of dynamically building an instance of a protocol when :extend-via-metadata is false? Is it possible short of generating bytecode?

arohner14:12:38

I’d like to do it dynamically, i.e. data driven. Let’s say I’m given the protocol definition var, a method symbol, and an fn, and I’d like to return an instance of the protocol that calls f. That’s easy to do when :extend-via-metadata is true. Is it possible to do when its false

Joshua Suskalo14:12:16

I mean with eval yes, but otherwise I'd say it'd require messing with internals if it's possible at all.

ghadi14:12:12

presumption that the protocol only has one arity?

arohner14:12:32

@U050ECB92 sure, if that makes it easier

ghadi14:12:01

you can automatically generate a proxy that delegates: (defn make-proxy [f] (reify (sig [this ...args] (f ...args))))

ghadi14:12:43

statically make one uber-proxy like above, or dynamically using eval (probably memoized by protofn)

arohner14:12:25

If I don’t know the signature of the protocol ahead of time, how do I build that proxy [edit] without eval?

arohner14:12:32

I guess I can call reify* directly

ghadi14:12:38

you can examine the arglists on the protofn var meta

ghadi14:12:32

you're not going to get away from calling eval if you can be passed an arbitrary protocol impl that you need to make

arohner15:12:10

I just need an existing function. I don’t need eval when :extend-via-metadata is true, so I find it plausible I can do it without. It looks like calling reify* directly might work, will investigate more

ghadi15:12:47

that reasoning doesn't follow

ghadi15:12:09

when extend-via-metadata=t, it doesn't require new classes (just maps with metadata)

ghadi15:12:32

when false, you'll need at least one new class that impls the protocol

ghadi15:12:51

new class => needs to go through the compiler

athos15:12:06

This seems to work (I guess it's an accidental behavior, though):

(defprotocol P (m [this]))
(extend (class conj) P {:m (fn [_] "conj")})

(m conj) ;=> "conj"

geeky_vin16:12:57

Hey Everyone, Need some help with Java Interop, Trying to write a Clojure version of this class --> https://docs.amazonaws.cn/en_us/neptune/latest/userguide/access-graph-gremlin-java.html Mainly creating the Cluster and GraphTraversalSource. I also had a look at Orge, Tinkerpop library for Clojure. But Couldn’t find any examples to connect to remote Gremlin Server. Any help will be much appreciated. Thanks!

jpmonettas18:12:41

for creating a Cluster object you can create it like :

(def builder (Cluster/build))
...
...
(def cluster (.create builder))
and then looks like you need to import org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource , like :
(ns ...
 (:import [org.apache.tinkerpop.gremlin.process.traversal AnonymousTraversalSource ...]
          ...))
so you can then do like:
(def g (.withRemote (AnonymousTraversalSource/traversal) (DriverRemoteConnection/using cluster))) 

jpmonettas18:12:49

does it make sense?

jumar19:12:55

Please don’t crosspost in multiple channels and if you do so then at least link your postings

👍 1
geeky_vin19:12:19

@U0739PUFQ thank you! this works!

dpsutton18:12:20

We bundle some 3rd party drivers into jar with jar uf metabase.jar modules/*.jar . This is throwing a java.lang.module.InvalidModuleDescriptorException: Unsupported major.minor version 61.0 . Our jar is a multi-release jar and as far as I can tell, it is because there is a classfile in there that is compiled against classfile 61 (java 17), but it is done in a way such that the multi-release should allow it. META-INF/versions/17/com/oracle/truffle/api/staticobject/StaticPropertyValidator.class I would expect that a multi-release jar can see classfiles it does not understand if they are in the versions/17/… format. Is this a wrong assumption? Can we not run jar uf … with java 11 if there are java 17 classfiles around in a multi-release format?

hiredman18:12:48

I am surprised jar is looking at file contents at all

hiredman18:12:21

actually, I bet I know what it is

hiredman18:12:15

the module-info.class in the jar is what has that major.minor version and is what is causing jar to barf, not the stuff under versions

hiredman18:12:33

which is why it is a java.lang.module.InvalidModuleDescriptorException

hiredman18:12:21

a very wild guess

dpsutton20:12:05

that sounds like a decent guess. Does that mean that jar cannot handle multi-release jars which contain class files for versions greater than the jdk being used? Seems like a weird thing and nothing seems obviously wrong here

Al Baker00:12:46

yes

cannot handle multi-release jars which contain class files for versions greater than the jdk being used

dpsutton00:12:56

Dang. Is that true? Documented anywhere? Seems wild that “java” can correctly ignore the Java 17 files there with the multi release jar but “jar” cannot

Al Baker00:12:38

as far as I can tell, not documented anywhere - but I treat that as "presume doesn't work". I'm actually amazed the older JRE doesn't yell at you for having the newer class files in there

Al Baker00:12:05

maybe it's a java 17 and newer thing...

dpsutton00:12:53

But Java 11 is aware of the multi release feature. Seems crazy it cannot ignore classfiles in a version it would not select for