Fork me on GitHub
#graalvm
<
2024-07-21
>
conao305:07:42

In relation to the previous question, is it possible to investigate how Clojure infers the return value of a function?

Alex Miller (Clojure team)13:07:35

It will use the function return type hint if it exists, otherwise assumes Object

conao300:07:36

Yes, how to get that information using some code?

conao300:07:43

function's metadata can be obtained with meta, but I think Clojure implements type inference

phronmophobic00:07:18

You can set to warn on reflection, (set! *warn-on-reflection* true). Usually, I just turn that on and fix the warnings as necessary. This talk gives a good overview, https://www.youtube.com/watch?v=s_xjnXB994w.

conao300:07:55

*warn-on-reflection* was told to me before, but I see a potential problem with all functions that fail type inference and am trying to display this in the editor. I would like to get this information from Clojure.

phronmophobic00:07:20

> but I see a potential problem with all functions that fail type inference Can you give a few more details about the problem?

phronmophobic00:07:53

What goal are you trying to achieve where using *warn-on-reflection* falls short?

conao300:07:11

That option will issue a warning at runtime, but this type of warning should be able to be issued statically.

phronmophobic00:07:34

You can get the warnings to show just by setting warn on reflection and loading the namespace. Do have a repl connected during development?

phronmophobic00:07:29

Especially for graalvm, which requires AOT compilation, you should see the warnings during compilation.

phronmophobic00:07:31

Some libraries set warn on reflection at the top of the namespace since they're intended to support native image compilation. For example, https://github.com/cnuernber/dtype-next/blob/a9d05cd39905394c7352496ea10de65e3e3475dd/src/tech/v3/datatype/wavelet.clj#L11.

conao300:07:37

You're right, sorry. No, I still think the main reason is that I think there is a potential problem. I will be able to write type hints on the fly when I don't guess the type I think I have at the moment I write the function.

conao300:07:48

It warn “when reflection occurs,” but I want to warn “code where reflection can occur.”

phronmophobic00:07:18

It warns on compilation.

phronmophobic00:07:43

user> (set! *warn-on-reflection* true)
user> (defn my-ends-with [s]
        (.endsWith s "laksdf"))
Reflection warning - call to method endsWith can't be resolved (target class is unknown).
#'user/my-ends-with

conao300:07:46

Yes, it is. But what if the call that causes the reflection is in a different namespace? It's not practical to evaluate all namespaces every time a function is changed.

conao300:07:41

Assumes that a function is defined in one namespace and called in another namespace.

phronmophobic00:07:58

Is this a problem you've run into or is this a theoretical problem?

phronmophobic00:07:45

You can set warn-on-reflection globally so that when you load a namespace or AOT compile it will also show warnings there too.

conao300:07:22

Theoretical. this time the problem is solved. I just want to receive warnings when I write a function, even when there is no call to it.

phronmophobic00:07:24

my-ends-with produces a reflection warning even though it is never called

conao300:07:01

https://github.com/conao3/clojure-graalvm-list-issue/blob/master/src/graalvm_list_issue/main.clj No. In this example, I want to start writing the source code from the top and notice that when I write local-dir, the type information is missing. I should be able to receive a warning without a call to .list with -main.

conao300:07:50

Maybe Clojure doesn't perform this kind of type inference in the first place, but I'd rather even implement it.

phronmophobic00:07:06

local-dir does not produce any reflection warnings

phronmophobic00:07:15

when you call .list, that is what produces the reflection warning

phronmophobic00:07:41

so when you write main, you can decide if you want to add type hints to local-dir or you can add type hints inline:

(defn -main [& _args]
  (println (seq (.list ^File (io/file (home-path) ".local"))))
  (println (seq (.list ^File (local-dir)))))

conao300:07:25

Sorry, I don't like to write type hints in the caller, it's not DRY, the problem is that the return type of local-dir is not guessed and I want to be aware of that fact.

conao300:07:14

And I think this type of type inference should be implemented in Clojure

phronmophobic00:07:30

Sounds good. I've written quite a bit of code that compiles to native image and I haven't really found it to be a problem. If you want to make a case for this type of inference, you can check if there's already an issue on https://ask.clojure.org/ and upvote or create a new question.

👍 1
phronmophobic00:07:39

fwiw, many common java utilities already have wrappers that avoid reflection. Specifically for file system utilities, you can try https://github.com/babashka/fs?tab=readme-ov-file

conao300:07:13

OK! thanks! I'm a Clojure beginner so I'll write more code and get more experience.

clojure-spin 1
🎉 1