java

2018-02-16T19:09:18.000361Z

I'm trying to "convert" the following java code to clojure:

public interface ITimeHandler {
		void currentTime(long time);
	}

	public void reqCurrentTime( ITimeHandler handler) {
...
	}
...
		controller().reqCurrentTime(time -> show( "Server date/time is " + Formats.fmtDate(time * 1000) ));
I've found that it works when I specifically implment the ITimeHandler interface:
(.reqCurrentTime controller
                 (reify com.ib.controller.ApiController$ITimeHandler
                   (currentTime [this arg]
                     (log/debug "the time is:" arg))))
But not with what I understand to be a regular java Function:
(.reqCurrentTime controller
                 (reify java.util.function.Function
                   (apply [this arg]
                     (log/debug "the time is:" arg))))
How is it that the example java code is able to "coerce" the lambda function to the appropriate interface? Am I not providing enough information here? There are a large number of these handler interfaces and I'm curious if I can create the handlers in a generic way, as the java code seems to be doing, rather than specifying each handler interface.

seancorfield 2018-02-16T19:30:00.000133Z

At compile time, Java knows which types are acceptable to the reqCurrentTime() function and it knows that is a one-function interface so the lambda it generates conforms to that interface.

seancorfield 2018-02-16T19:31:07.000314Z

Basically Java doesn't just turn lambdas into Function instances -- it tailors it to suit the call site.

seancorfield 2018-02-16T19:31:51.000114Z

I suspect that if you created the lambda in a different context, you would not be able to pass it to reqCurrentTime()...

seancorfield 2018-02-16T19:32:35.000643Z

(at least, that's my understanding of how Java lambdas work @jjttjj -- hopefully someone will correct me if they have more insight into this!)

2018-02-16T19:34:06.000280Z

@seancorfield gotcha, thank you