Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Clojure by
(ns graalvm-list-issue.main
  (:require
   [clojure.java.io :as io])
  (:gen-class))

(defn- home-path []
  (System/getProperty "user.home"))

(defn- local-dir []
  (io/file (home-path) ".local"))

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

(Full code is here: https://github.com/conao3/clojure-graalvm-list-issue)

The first println line has no reflection, the second println line has reflection, and an error occurs during execution in GraalVM.
I see no difference between the two calls, and since it is obvious that it is io/file as the return value of local-dir, it should be type-inferred as java.io.File. What do you think?


Investivate Clojure source code:

Key function is hasJavaClass and getJavaClass.
https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L359-L361

FnExpr: https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L4450-L4454

InvokeExpr: https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L4286-L4290

2 Answers

0 votes
by

local-dir effectively returns Object, as all functions do in Clojure without return type hints. There is no inference here.

You could hint it to return File: (defn- local-dir ^java.io.File [] ..)

Then you won't get reflection.

by
Analyzing the code, it is obvious that the return value of `io/file` is the return value of the function, and since the return value of `io/file` is `java.io.File`, we should be able to guess that the return value of the function itself is also `java.io.File`.
0 votes
by

While this seems obvious in this example, once you introduce conditionals / multiple tail positions, and primitives, it becomes quite a bit more complicated. With multiple tail positions, it's pretty common for the answer to really be multiple answers - presumably you would need to then find a common supertype or omit in that case.

Also, because type hints are primarily useful for Java interop, the cases where you actually need the return type hint are relatively small (many programs may have no cases of it).

At the current time, the effort involved to produce something of limited use is probably not worth it, but maybe something to look at in the future.

...