Code that runs fine in repl not compiles when running from command line

This code runs fine in repl

user=> (import 'org.lwjgl.glfw.GLFW)
org.lwjgl.glfw.GLFW
user=> (import 'org.lwjgl.glfw.GLFWKeyCallbackI)
org.lwjgl.glfw.GLFWKeyCallbackI
user=> (GLFW/glfwSetKeyCallback 0 (reify GLFWKeyCallbackI (invoke [this w k s a m])))
Execution error (NullPointerException) at org.lwjgl.system.Checks/check (Checks.java:100).
null
user=>

bit this code

(let [p-win  (GLFW/glfwCreateWindow width height title MemoryUtil/NULL MemoryUtil/NULL)
      key-cb (reify GLFWKeyCallbackI
               (invoke [this window key scancode action mods]))]
  (GLFW/glfwSetKeyCallback​ p-win key-cb))

does not compile when I’m trying to run it

Syntax error (IllegalArgumentException) compiling . at ...
No matching method glfwSetKeyCallback found taking 2 args for class org.lwjgl.glfw.GLFW

Why? I tried to hint types (https://clojure.org/reference/java_interop#typehints) but that didn’t help

In the repl example, you’re actually passing in 0, which is initialized as a long automatically by the reader. So the compiler can infer the type of the first arg. The second arg is reifying an interface, and I’m guessing the compiler is smart enough to determine that type as well.

In the second example, you never type what p-win is, or key-cb. I’d be willing to bet of those were hinted you would be okay.

(GLFW/glfwSetKeyCallback​ (long p-win) ^GLFWKeyCallbackI key-cb)

Based on the javadoc It looks like the method expects a primitive long and GLFWKeyCallbackI as arg types.

Since there are no type hints, it’s trying to find a method invocation for Object Object, which doesn’t exist (I think).

I tried hinting types the way you suggested, but it still did not work.
I guess to invoke Java methods Clojure uses runtime reflection in repl and compile-time reflection when running code from command line, and in repl it can find method successfully, but somehow it can not do so when compiling.
Is it possible to not compile at all when running it like clj -m foo.core?

Ok so the problem was that for some reason I had zero-width space in code (revealed below as seen in vim)

(GLFW/glfwSetKeyCallback<200b> p-win key-cb)

so the actual symbol was not …Callback, but …Callback<200b>, and those two are visually indistinguishable.

Oh mighty mangoes, being a computer programmer is hard

2 Likes

Last thing I expected. Glad you solved it.