Fork me on GitHub
#cursive
<
2020-08-01
>
onetom12:08:26

I'm getting a Cannot disambiguate overloads of ProcessBuilder warning from Cursive in the (defn build-process [cmd] ... (java.lang.ProcessBuilder. cmd) ...) expression. It also manifests at runtime as this message:

Reflection warning, /Users/onetom/.../src/testbed.cljc:92:9 - call to java.lang.ProcessBuilder ctor can't be resolved.
I tried to add ^List in front of cmd and that made the issue go away, but List is not defined in Babashka...

onetom12:08:31

what is the most generic type I should use in these situations? the constructor is defined to accept "var-args" and I read somewhere, to call such functions, Clojure should provide them with some array-ish thing.

onetom13:08:25

(require '[clojure.reflect :as r])
(import '[clojure.reflect Constructor])
(->> (r/type-reflect ProcessBuilder)
     :members
     (filter (comp #{Constructor} type)))

(#clojure.reflect.Constructor{:name java.lang.ProcessBuilder,
                              :declaring-class java.lang.ProcessBuilder,
                              :parameter-types [java.util.List],
                              :exception-types [],
                              :flags #{:public}}
 #clojure.reflect.Constructor{:name java.lang.ProcessBuilder,
                              :declaring-class java.lang.ProcessBuilder,
                              :parameter-types [java.lang.String<>],
                              :exception-types [],
                              :flags #{:varargs :public}})

onetom13:08:19

I'm wondering if there is a literal form for java.lang.String<> to use it as a type hint 😕

onetom13:08:49

^Ljava.lang.String or ^java.lang.String<> doesn't work..

borkdude13:08:21

@U086D6TBN This works with both bb and clj:

$ bb -e '(set! *warn-on-reflection* true) ((fn [& args] (ProcessBuilder. ^java.util.List args)) "ls")'

borkdude13:08:38

So you get your reflection avoided and also compatible with bb

borkdude13:08:24

List is not a thing both in bb and clj without importing it or fully qualifying it

onetom13:08:57

bb -e '(import (quote [java.util List])) ((fn [& args] (ProcessBuilder. ^List args)) "ls")'
java.lang.Exception: Unable to resolve classname: java.util.List [at line 1, column 1]

onetom13:08:19

i was importing it in Clojure and as i mentioned it made Cursive happy, but not bb

onetom13:08:41

Cursive recommends using the short form of fully qualified class references; that's how I cornered my self 🙂

borkdude13:08:18

Ah right, bb allows you to use type hints without actually needing those classes to be in bb

borkdude13:08:26

just for compatibility

onetom13:08:56

i can't remember reading about this in the bb docs so far. might worth mentioning it

borkdude13:08:36

it will try to use the type hint if it can resolve the class

onetom13:08:31

i feel like to make bb a good alternative to bash, using any kind of external process related functionality should be really friendly

borkdude13:08:43

I think it might be better to just add the java.util.List class to bb (I was kind of surprised it wasn't already in there)

borkdude13:08:18

If vec would have a return type tag on it, one could do this with (ProcessBuilder (vec args)) right?

onetom14:08:00

are you asking me? i don't know. i didn't have to deal with type metadata much on my clojure journey so far 🙂 im not even sure where should the return type tag go. on the var or the arg vector...

onetom14:08:44

which is i think a testament to how practical clojure is 🙂 i've trained a few people clojure over the past ~5 years. wrote a bunch of useful programs, even in clojurescript with hoplon, yet there was hardly any need to deal with type tags.

borkdude14:08:10

If you use this function:

(defn vec2 ^clojure.lang.PersistentVector [x]
  (vec x))
around your arguments to ProcessBuilder, the reflection warning goes away, because PersistentVector implements List. Maybe there's a reason why clojure.core doesn't have the type tag on vec as of now. @U064X3EF3?

Alex Miller (Clojure team)15:08:50

Generally, collections are never hinted with the concrete type - it just relies on polymorphism are the call site

Alex Miller (Clojure team)15:08:53

The return here is not necessarily that type either

Alex Miller (Clojure team)15:08:34

If you make your own concrete vector collection, and call vec on it, you’d get that type

borkdude15:08:20

ok, makes sense