3

I was writing a client/server test, and ran into something unexpected. In the following code, the port argument of the Socket constructor isn't able to be inferred:

(ns second-try.test.client
  (:import [java.net Socket]))

(def port 5555)

(defn -main []
  ; "Cannot disambiguate overloads of Socket"
  (let [sock (Socket. "127.0.0.1" port)]))

The type of the first argument should be obvious since I'm passing a literal. I would think the type of the port would be obvious too since again, it's just a literal; albeit one tucked away behind a def.

For some reason though, it can't figure out the type of port. I can remedy it by putting an annotation on either the def, or in front of the argument, but why is this necessary? Shouldn't it be obvious to it what the type is?

Nathan Davis
  • 5,636
  • 27
  • 39
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • What can't figure out the port? The code runs fine on my machine. If the problem is with Cursive see [this answer](http://stackoverflow.com/questions/32472894/how-to-disambiguate-in-clojure). – user2609980 Jan 14 '17 at 22:45
  • @ErwinRooijakkers I am using Cursive, so that could be it. – Carcigenicate Jan 14 '17 at 23:45

2 Answers2

3

It's not really possible to infer the type of the value stored in a var in Clojure, because a var can be re-defined at any time.

However, Clojure shouldn't have any problem determining the type at run-time and, although it will require the use of reflection to disambiguate at run-time, the code in question should (and does) run.

The error appears to be related to Cursive: https://stackoverflow.com/a/32473508/440294

Adding a type-hint ... to specify which overload you expect to use would remove the need for reflection and hopefully calms Cursive down.

In your case, I'd try something like:

(defn -main []
  ; "Cannot disambiguate overloads of Socket"
  (let [^int p port
        sock (Socket. "127.0.0.1" p)]))
Community
  • 1
  • 1
Nathan Davis
  • 5,636
  • 27
  • 39
2

In this case, just declare you var to be :const:

(def ^:const port 5555)

(defn -main []
  (let [sock (Socket. "127.0.0.1"  port)]))
ClojureMostly
  • 4,652
  • 2
  • 22
  • 24