Unresolved instance method invocation

59 views
Skip to first unread message

cristian....@gmail.com

unread,
Mar 12, 2014, 10:02:27 PM3/12/14
to clojure-c...@googlegroups.com
I do a couple of method calls of java classes. For example:

(.println *err* "Error")

core.typed gives me an error:

ExceptionInfo Unresolved instance method invocation println.

Hint: add type hints

I'm assuming the problem is that core.typed cannot determine the type of *err* (in this case), but putting an annotation `(ann clojure.core/*err* java.io.PrintStream)` doesn't solve the problem.

Is there another function I should call?

Thanks,
Cristian

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 12:01:42 AM3/13/14
to core.typed
Hi Cristian,

You need to add type hints to avoid reflection.

user=> (set! *warn-on-reflection* true)
user=> (.println *err* "foo")
Reflection warning, /tmp/form-init260135491385563205.clj:1:1 - call to println can't be resolved.
foo
nil
user=> (.println ^java.io.PrintWriter *err* "foo")
foo
nil

Thanks,
Ambrose

cristian....@gmail.com

unread,
Mar 13, 2014, 2:34:46 AM3/13/14
to clojure-c...@googlegroups.com

Hi Ambrose,

Thanks for the advice, but I seem to stuck between two different errors:

user=> (t/cf (.println ^java.io.PrintWriter *err* "foo"))
foo
Type Error (NO_SOURCE_FILE:1:7) Cannot call instance method java.io.PrintWriter/println on type java.io.Writer
in: (.println clojure.core/*err* foo)

Okay, so core.typed thinks *err* is a java.io.Writer object, which should be fine since Writer is the parent of PrintWriter, but when I try that I get:

user=> (t/cf (.println ^java.io.Writer *err* "foo"))
Reflection warning, NO_SOURCE_PATH:1:7 - call to println can't be resolved.
foo

ExceptionInfo Unresolved instance method invocation println.
Hint: add type hints.
in: (.println clojure.core/*err* "foo")  clojure.core/ex-info (core.clj:4327)

Is there another way to force the type of *err*?

Thanks,
Cristian

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 3:03:29 AM3/13/14
to core.typed
Hi Cristian,

Ah. It's my understanding that Clojure promises *err* to be a java.io.Writer, so that's the annotation
it gets.

If core.typed understood cast, you would use (cast java.io.PrintWriter *err*).

Unfortunately it's NYI.

This is the best I could do.

clojure.core.typed=> (cf (let [err *err* _ (assert (instance? java.io.PrintWriter err))] (.println ^java.io.PrintWriter err "foo")))
foo
nil

Thanks,
Ambrose

Cristian Esquivias

unread,
Mar 13, 2014, 3:42:14 AM3/13/14
to clojure-c...@googlegroups.com
Excellent. I was able to get passed the error. I'm amassing a nice little suite of workarounds ;)

Thanks for the help and the work on core.typed,
Cristian

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 5:54:30 AM3/13/14
to core.typed
If anyone wants to help implement support for cast, the ticket is here


Thanks,
Ambrose

Di Xu

unread,
Mar 13, 2014, 6:34:44 AM3/13/14
to clojure-c...@googlegroups.com
I think if we want to support for cast, we have to provide some sort of ClassOf type, and then annotate it as (All [c x] [c x -> (ClassOf c)).

Is that so?


Thanks,
Di Xu

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 6:45:10 AM3/13/14
to core.typed
Interesting idea, but it's easier to add a special case like instance-of


Thanks,
Ambrose

Di Xu

unread,
Mar 13, 2014, 6:59:20 AM3/13/14
to clojure-c...@googlegroups.com
eh, I was thinking about
annotate using `add-invoke-special-method`, what's the different?

Thanks,
Di Xu

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 7:10:28 AM3/13/14
to core.typed
Right, that's how you'd add support for cast.

instance? is special, and gets analysed to a :instance-of expression; it's not
a normal invoke.

Thanks,
Ambrose

Di Xu

unread,
Mar 13, 2014, 7:30:40 AM3/13/14
to clojure-c...@googlegroups.com
I've attached a patch, I'm not sure if we should test if second to `cast` is constant or not.

If it's constant, maybe we should return it's type to narrow down the output type, but since 1, "a", 'S and 1.2 have different :op using `jvm.tools.analyzer`, I think it's better to see if the other ast generator you're going to use parse them as :op :constant or not, and after then we can provide better type output.


Thanks,
Di Xu

Ambrose Bonnaire-Sergeant

unread,
Mar 13, 2014, 7:37:25 AM3/13/14
to core.typed
Thanks Di, I commented on the patch.

Ambrose
Reply all
Reply to author
Forward
0 new messages