Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to translate the double colon operator to clojure?

Tags:

java

clojure

I discovered a new syntax for java 8 reading through the source for a framework I'm attempting to wrangle:

 Runtime.getRuntime().addShutdownHook(new Thread(Sirius::stop));

In clojure, I can translate it as:

(.addShutdownHook (Runtime/getRuntime) (Thread. ????))

But I'm not sure what to put for the ???


like image 765
zcaudate Avatar asked Mar 21 '15 05:03

zcaudate


2 Answers

IFn extends Runnable, so you can just do

#(Sirius/stop)

It is worth noting that

  • You have to make the lambda. Clojure won't let you refer to it just as Sirius/stop
  • Java 8 functional interfaces under the hood work by making anonymous implementations of interfaces with only one method. So

    new Thread(Sirius::stop)

is just syntactic sugar for

new Thread(new Runnable {
    public void run() {
        Sirius.stop();
    }
})

If the interface in question isn't Runnable/Callable, you'll have to use the reify macro.

like image 138
George Simms Avatar answered Sep 17 '22 03:09

George Simms


@george-simms has the correct explanation, but for anyone who is looking for an example which is not a Runnable/Callable, and need to use reify, here it is.

Say you want to use the DateTimeFormatter parse method like this:

DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE();
LocalDate d = dtf.parse("2019-04-04", LocalDate::from);

You need to check the Functional interface type of the second param of parse, which is TemporalQuery in our case. That means, you need to reify TemporalQuery, and implement its only method (Functional interfaces always have only one method), so that it calls the static method from on the LocalDate class. So in Clojure it would translate too:

(import 'java.time.format.DateTimeFormatter)
(import 'java.time.temporal.TemporalQuery)
(import 'java.time.LocalDate)

(let [dtf (DateTimeFormatter/ISO_LOCAL_DATE)]
  (.parse dtf "2019-04-04"
          (reify TemporalQuery
                 (queryFrom [this temporal]
                            (LocalDate/from temporal)))))
like image 37
Didier A. Avatar answered Sep 17 '22 03:09

Didier A.