There isn’t one for “surrounding sexp”, but if you have a form selected then all the “Send xxx to REPL” actions will send that instead of what they would normally send. So you can select the form using Alt-up arrow and then use Cmd-P.
Which version of Cursive are you using? There was a bug with this which was fixed in 1.9.2.
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...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.
(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}})
I'm wondering if there is a literal form for java.lang.String<>
to use it as a type hint 😕
^Ljava.lang.String
or ^java.lang.String<>
doesn't work..
@onetom This works with both bb and clj:
$ bb -e '(set! *warn-on-reflection* true) ((fn [& args] (ProcessBuilder. ^java.util.List args)) "ls")'
So you get your reflection avoided and also compatible with bb
List
is not a thing both in bb and clj without importing it or fully qualifying it
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]
i was importing it in Clojure and as i mentioned it made Cursive happy, but not bb
Cursive recommends using the short form of fully qualified class references; that's how I cornered my self 🙂
Ah right, bb allows you to use type hints without actually needing those classes to be in bb
just for compatibility
i can't remember reading about this in the bb docs so far. might worth mentioning it
it will try to use the type hint if it can resolve the class
i feel like to make bb a good alternative to bash, using any kind of external process related functionality should be really friendly
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)
If vec
would have a return type tag on it, one could do this with (ProcessBuilder (vec args))
right?
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...
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.
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. @alexmiller?Generally, collections are never hinted with the concrete type - it just relies on polymorphism are the call site
The return here is not necessarily that type either
If you make your own concrete vector collection, and call vec on it, you’d get that type
ok, makes sense