clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
marciol 2021-06-15T17:03:15.408200Z

Hi all, I'm reading about the FFI and Java, and I wondering what the JEP 393 [1] will mean in the world of native integration regarding Clojure. Seems that the public state of the art is condensed in this article [2] from @chris441, but I'd like to know what you all think about it. [1]: https://openjdk.java.net/jeps/393 [2]: https://techascent.com/blog/next-gen-native.html

chrisn 2021-06-17T12:33:23.477200Z

The foreign pathway definitely works and is quite fast, faster than JNA direct mapping or JNR by a bit but for instance when I used it with Python the python runtime could not find the numpy module which was very very odd so there exist some low level differences there to be worked out.

chrisn 2021-06-17T12:34:28.477400Z

It worked fine with avclj, that is for sure. Speaking of which to take avclj (or something like it) further there is a cool python wrapper done in the same way (linking to the ffmpeg shared librarries) that has a good sort of filter-based interface. I can't remember the name offhand.

marciol 2021-06-17T23:45:18.031200Z

Nice to hear about your experiences. I think that OpenJDK is condensing all improvements for java 17 on this umbrella https://openjdk.java.net/jeps/412 This is a subject that caught my attention, so I intend to understand how this stuff interacts with the dtype-next.

chrisn 2021-06-18T13:32:28.067300Z

The memory model stuff (memory segments, writing to native memory) I don't use much aside to get an integer pointer as I already use sun.misc.unsafe for writing/reading to native memory. The ffi stuff, CLinker and friends I use when I generate jdk-16 FFI bindings and I do this using a library named insn https://github.com/cnuernber/dtype-next/blob/master/src/tech/v3/datatype/ffi/mmodel.clj. There could conceivably be a JDK-16 specific version of dtype-next that doesn't use unsafe at all and thus doesn't required restricted access but some parts of the memory model specification - regions - I have absolutely no use for as dtype-next uses the https://github.com/techascent/tech.resource to bind objects that need a dispose-or-free-type operation to the GC or stack frame as needed.

chrisn 2021-06-18T13:32:57.067600Z

One thing to note as that graalvm has two completely different and unrelated FFI pathways of which I support one of.

marciol 2021-06-15T17:03:30.408400Z

Let's discuss on this thread 😄

phronmophobic 2021-06-15T17:15:35.408600Z

I've recently been trying dtype-next and it's pretty great.

phronmophobic 2021-06-15T17:17:20.408800Z

I've used ffi to access a few c libraries from clojure and it's been interesting to see that the c apis are often more clojure-friendly then many of the java APIs. Corollary: using ffi to directly talk to a native library is almost always better than trying to use a Java library that wraps a native library.

phronmophobic 2021-06-15T17:22:41.409100Z

There are a couple libraries I have my eye on: • libclang: I want to parse c headers and have it produce the c<->clojure api for other libraries • graphviz: shelling out to dot is ok, but directly talking to the c api could be better. • ffmpeg: there's already avclj, but more of ffmpeg's capabilities can still be wrapped more idiomatically.

antonmos 2021-06-15T18:32:58.410800Z

Does anyone use datadog's javaagent in their clojure app? I gave it at try, but saw that the app took 5x time to start up.

👋 1
1
kenny 2021-06-15T18:57:30.412200Z

We use it and have not experienced that. If it matters, we AOT compile prod artifacts.

lilactown 2021-06-15T19:03:11.413400Z

what are the cases when Throwable-&gt;map would return multiple maps under the :via key?

jmv 2021-06-15T19:15:57.413500Z

i have only noticed a very slow start when instrumentation debugging is on

2021-06-15T19:17:35.413700Z

chained exceptions? if an exception has a cause set using initCause

2021-06-15T19:19:08.413900Z

that's all i can see from the source code of that function

alexmiller 2021-06-15T19:29:49.414100Z

yes, chained exceptions

2021-06-15T19:39:43.414300Z

also, initCause isn't the only way to chain them. Throwable constructor accepts the cause as well

stephenmhopper 2021-06-15T21:02:56.415700Z

Can I use the fancy new protocol :extend-via-metadata true functionality with Java interfaces somehow? Here’s a contrived example that doesn’t work. What’s the quickest way to make this work?

(def thing
  (with-meta {}
    {'clojure.lang.IDeref/deref
     (fn [this]
       "some value")}))

(deref thing)

seancorfield 2021-06-15T21:15:41.416600Z

@stephenmhopper No, only protocols. You probably want to look at reify for interfaces.

dpsutton 2021-06-15T21:15:52.417Z

example

(let [x (reify clojure.lang.IDeref
          (deref [_] :foo))]
  @x)
:foo

☝️ 1
1
2021-06-15T22:53:34.419Z

Quick question about print-dup, is it intended to preserve metadata?

2021-06-15T22:54:03.419200Z

I'd imagine not

2021-06-15T22:54:40.419500Z

Although it looks like it does based on the implementation for persistent map

dpsutton 2021-06-15T22:56:13.420100Z

can you explain your question a bit more?

2021-06-15T22:57:11.421400Z

it is, but print-dup is super rarely used

2021-06-15T22:57:15.421500Z

print-dup is a multimethod for basic serialization, most of the time it constructs read-time evaluation forms. I'm just curious if it's in general intended to produce readable metadata forms as well as the actual data structure itself.

2021-06-15T22:57:18.421700Z

That's fair.

2021-06-15T22:58:13.422300Z

to some degree the use of print -dup is an anti-pattern because it is too specific

2021-06-15T23:01:57.423600Z

That's fair, but I'm not really one to judge what the usage of the library would be. I'm just writing a general ropes library since the existing one only works on byte arrays.

2021-06-15T23:02:23.424500Z

And since the core data structures support print-dup, so will I

2021-06-15T23:02:53.425100Z

user=&gt; (doc *print-dup*)
-------------------------
clojure.core/*print-dup*
  When set to logical true, objects will be printed in a way that preserves
  their type when read in later.

  Defaults to false.
nil
user=&gt; (alter-var-root #'*print-dup* (constantly true))
true
"user=&gt; "{}
#=(clojure.lang.PersistentArrayMap/create {})
"user=&gt; "
the one place I've seen print-dup used outside of the compiler (and I am pretty sure that ended up being a mistake) prn was used and *print-dup* was bound to true, print-dup wasn't called directly

2021-06-15T23:04:06.426200Z

Yeah, it's intended mostly to be used with prn or pr-str to my understanding

2021-06-15T23:04:08.426300Z

in the compiler print-dup gets used for serializing arbitrary objects into byte code

2021-06-15T23:04:49.427200Z

so for example if a macro expansion contained one of your rope data structures (not the code to create one)

2021-06-15T23:05:20.427400Z

Ah, makes sense.