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.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.
Basically Java doesn't just turn lambdas into Function
instances -- it tailors it to suit the call site.
I suspect that if you created the lambda in a different context, you would not be able to pass it to reqCurrentTime()
...
(at least, that's my understanding of how Java lambdas work @jjttjj -- hopefully someone will correct me if they have more insight into this!)
@seancorfield gotcha, thank you