Java 8 came out in 2014 and brought along functional interfaces. Functional in general just means that you can treat functions (or methods) as “things” instead of having no proper way to talk about them. In this sense Javascript for example is functional: you can pass around functions all you want. Java’s had Runnable and Callable that are pretty similar in concept.

Then came Java 8 and with it the “mighty arrows.” For some reason Ruby, Javascript and Java all opted to use the same bit of syntax to talk about lambdas (anonymous functions): ->. In Ruby it’s ->(foo) { foo }, in Javascript it’s (foo) -> foo, and surprisingly in Java it’s the same. Run a few rounds with futures and/or streaming stuff and you’ll definitely want to pass such a lambda to forEach for example.

Java of course is statically typed so these “things” must be some type as well, right? Turns out there’s plenty of compiler magic going on, so it’s not as simple as implementing call and be happy. Looking at the documentation, there’s a whole bunch of “functional interfaces” that each have some abstract method (differing by the interface) the “implementing” lambda “replaces.”

For example Stream‘s forEach wants a Consumer (and that’s what usually forEach‘s want), which means your lambda must take one argument and return void (in practice, null), because that’s the signature of Consumer‘s abstract accept.

Back in Clojure-land, we’ve got our beloved IFn functions that really should be as functional as functional gets. The problem is that Clojure’s idea of functional is different from Java’s and while IFns implement Runnable and Callable, 6 years after Java 8 came out (and 2 years after a relevant “critical” ticket was filed) they still don’t implement any of the functional interfaces. Talk about a “stable API.”

I delved into this matter because I noticed athos‘s power-dot repo. It’s an amazing work of macro magic and reflection. I had to wonder if it could be done any simpler.

I decided to go the way of the reader macro: define my own tagged literal in data_reader.clj and make sure the namespace is required.

(ns my.reader)

(defn functional-fn
  [f]
  `(reify
     java.util.function.Consumer
     (accept [this# arg#]
       (~f arg#))

     java.util.function.Function
     (apply [this# arg#]
       (~f arg#))

     java.util.function.Predicate
     (test [this# arg#]
       (~f arg#))

     java.util.function.Supplier
     (get [this#]
       (~f))))

Of course this only covers the most common cases and probably vomits really nasty stacktraces if there’s an arity mismatch, but it’s better than nothing. With {F my.reader/functional-fn} in a data_readers.clj and after requiring my.reader (seems necessary, alas), I can just throw things as forEach‘s and filter my Streams without thinking about how many baby pandas had to be sacrificed for this.

user=> (.forEach [1 2 3] #F #(println %))
1
2
3
nil

The problem with this is something that’d definitely be brought up as a weakness of staticly typed languages: the proliferation of types. You can define your own “functional interface” by either letting the compiler figure it out (if you have exactly one abstract method) or marking it with @FunctionalInterface (or in the case of Clojure ^FunctionalInterface). So a perfectionist Clojure would have to figure out a way to deal with that.

The compiler should have all the needed info (that a reader function doesn’t get) (or else throw a reflection warning): the called class, the method name… Of course it gets tricky if the called class had multiple forEach‘s for example with different “functional” interfaces that behaved differently. Use the first? Demand a type hint? Anything is better than nothing. Either way, it doesn’t get much “simpler” than what power-dot does, not without the compiler’s power.