Fork me on GitHub
#clojure-dev
<
2019-07-01
>
ikitommi11:07:20

any plans in making this true?

(instance? java.util.function.Function (fn []))

ikitommi11:07:51

would help a lot with the Java interop.

ikitommi11:07:35

Currently writing code like this:

CompletableFuture
  (-send-response [response exchange]
    (.dispatch
      ^HttpServerExchange exchange
      SameThreadExecutor/INSTANCE
      ^Runnable (^:once fn* []
                  (.thenApply
                    response
                    ^Function (reify Function
                                (apply [_ response]
                                  (-send-response response exchange)
                                  (.endExchange ^HttpServerExchange exchange)))))))

Alex Miller (Clojure team)12:07:36

We looked at it some for 1.10 and will probably take another swing at it in 1.11

Alex Miller (Clojure team)12:07:09

I can’t search right now but there is a jira for it

Alex Miller (Clojure team)12:07:26

that's the one, Ghadi's been working on it off and on

ghadi13:07:10

@ikitommi one thing we're thinking about is whether we can add the proper SAM interface to IFn automatically based on context. Not just for j.u.f.Function

👌 4
cfleming20:07:38

@ghadi Do you mean doing SAM conversion for IFns? I would love that.

ghadi20:07:53

it would be really cool but it's tricky

cfleming20:07:01

I have no doubt.

cfleming20:07:20

But 💯 from me.

ghadi20:07:43

the goal would be to not have to specify SAM classnames or the SAM name itself

cfleming20:07:17

I guess it’s tricky because of overload resolution?

ghadi20:07:41

(.setUncaughtExceptionHandler (Thread/currentThread) (fn [t e] ....))

ghadi20:07:46

if we could make that work ^

ghadi20:07:05

the argument to setUncaughtExceptionHandler is a Thread$UncaughtExceptionHandler, which is a SAM

cfleming20:07:14

How is that different from full SAM conversion?

ghadi20:07:16

would be cool to auto-attach that interface to the fn

cfleming20:07:31

Yes, it absolutely would.

gfredericks20:07:33

so would only work if the fn is inline?

ghadi20:07:59

no way to generically do that through vars

cfleming20:07:11

So you wouldn’t create wrapper interfaces in other cases?

gfredericks20:07:22

could you do it with a defn if the user annotates it?

ghadi20:07:37

there are a lot of different things to explore here 🙂

ghadi20:07:55

you could dynamically spin adapters too, with indy

ghadi20:07:20

(.setUncaughtExceptionHandler (Thread/currentThread) (fn [t e] ....)) for that to execute without a ClassCastException, the third argument must be a Thread$UncaughtExceptionHandler,

ghadi20:07:56

whether it is an IFn too doesn't matter

ghadi20:07:21

my challenge is: can you do it without having to name that class?

ghadi20:07:05

(which would mean you need to propagate the calling context of setUncaughtExceptionHandler into the analysis of the fn)

ghadi20:07:20

or dynamically adapt fn with invokedynamic

cfleming20:07:41

Surely you wouldn’t need to do that if you just created a wrapper class at the invocation point?

ghadi20:07:03

that == which?

ghadi20:07:16

the extra calling context analysis?

cfleming20:07:18

(reify Thread$UncaughtExceptionHandler (uncaughtException [t e] (my-fn t e))

cfleming20:07:35

i.e. you wouldn’t need to extend the analysis of IFn

ghadi20:07:06

how do you know when to adapt vs. not?

gfredericks20:07:15

again only with literals, maybe?

ghadi20:07:16

if someone provides a Thread$UncaughtExceptionHandler

cfleming20:07:17

Always adapt

ghadi20:07:25

wrappers suck

cfleming20:07:29

And let hotspot deal with it.

ghadi20:07:39

you can write wrappers in userspace at your delight

cfleming20:07:51

The problem is I don’t delight in doing it.

ghadi20:07:14

not a wrapper but some helpers ^

ghadi20:07:47

with a wrapper, who looks up the proper classname @cfleming?

cfleming20:07:12

How do you mean?

cfleming20:07:05

Ugh, I really have to run, sorry, but I’m very interested in this.

ghadi20:07:12

what triggers the emission of (reify Thread$UncaughtExceptionHandler (uncaughtException [t e] (my-fn t e))?

cfleming20:07:53

Right, the problem in a dynamic lang is knowing what you have, I guess.

ghadi20:07:54

just wanted to say that extending IFn to j.u.function.Function is only 1% of the problem

ghadi20:07:00

which was suggested earlier

Alex Miller (Clojure team)21:07:43

if it was easy, it would already be done :)

ghadi21:07:30

there probably exist 0 use cases of things that need the functional interface && IFn

ghadi21:07:52

when you want to interop with the functional interface, you no longer care about IFn