java

2024-08-01T13:24:08.141429Z

I can't seem to get java varargs working in clojure for one out of two of the cases from the https://docs.oracle.com/en%2Fjava%2Fjavase%2F22%2Fdocs%2Fapi%2F%2F/java.base/java/lang/foreign/MemoryLayout.html#variable-length-toplevel. (I think these particular classes are only in java 21+, I'm using java 22) Java:

StructLayout POINT = MemoryLayout.structLayout(
            ValueLayout.JAVA_INT.withName("x"),
            ValueLayout.JAVA_INT.withName("y")
);

VarHandle POINT_ARR_X = POINT.arrayElementVarHandle(PathElement.groupElement("x"));
Clojure:
(ns layout
  (:import [java.lang.foreign
            MemoryLayout$PathElement
            MemoryLayout
            ValueLayout
            MemorySegment]))

;;; Works
(def POINT
  ;;Signature: static StructLayout structLayout(MemoryLayout... elements)
  (MemoryLayout/structLayout
    (into-array MemoryLayout [(.withName ValueLayout/JAVA_INT "x")
                              (.withName ValueLayout/JAVA_INT "y")])))


;;; Doesn't work


;;Signature: VarHandle arrayElementVarHandle(MemoryLayout.PathElement... elements)
(.arrayElementVarHandle POINT
  (into-array MemoryLayout$PathElement [(MemoryLayout$PathElement/groupElement "x")]))

;;Execution error (IllegalArgumentException) at layout/eval146 (REPL:1).
;;No matching method arrayElementVarHandle found taking 1 args for class jdk.internal.foreign.layout.StructLayoutImpl
I tried on the most recent clojure 1.11 and 1.12beta3. Anyone know what's going on here?

Alex Miller (Clojure team) 2024-08-01T13:31:26.854029Z

at a skim, looks like you are doing things that should work. does type hinting POINT in the last call help?

✅ 1
2024-08-01T13:31:59.950099Z

Yup, that does it, thanks!

Alex Miller (Clojure team) 2024-08-01T13:32:54.443039Z

the type of POINT is lost in the def, so it's reflecting and using StructLayoutImpl as the class, which might be confusing things, esp if you are into native goo

Alex Miller (Clojure team) 2024-08-01T13:33:44.392789Z

wouldn't hurt to add (set! warn-on-reflection true) at the top under the ns call and then make sure you are not getting warnings

👍 1