Fork me on GitHub
#clojure
<
2021-01-30
>
aratare16:01:21

Hi there. I have a setup with both Clojure and Java files where I'm using Clojure as a wrapper and Java as a lower layer to work with other things. Is there a way, from Java, to print to whatever Clojure's out is? Thanks in advance.

borkdude16:01:29

@rextruong If you are calling a Java component from Clojure, you can just pass *out* as an argument and then .write to that

aratare16:01:27

Unfortunately I'm not able to pass any additional info from Clojure to Java since I can't touch the method signature.

aratare16:01:56

Though that being said I can just put it as a class property and use it instead :thinking_face:

aratare16:01:10

Will give it a try. Thanks 🙂

aratare16:01:24

Yep seems like a great solution. Thanks a lot 🙂

borkdude16:01:37

what is a class property?

aratare16:01:07

public class Foo {
    private int bar;
}
bar is a class property. Though my terminology may be a bit wonky.

aratare16:01:53

Actually it's a class field.

noisesmith16:02:32

you can use Clojure.*var*("clojure.core", "*out*"); to get the root binding of out

noisesmith16:02:32

you still need to deref that though if used from java

borkdude16:02:56

The root binding is probably not so interesting since it's just a stream to stdout

noisesmith16:02:56

that's fair, but in order to know a specific binding, you would need to have your handle on a specific thread / context. which is implicit in clojure but it's a weird hoop to jump through if interacting with clojure via java

borkdude16:02:40

@U051SS2EU He is calling Java from Clojure. So you can just pass *out* as an argument which will pass the dynamically bound value to the Java side

noisesmith16:02:57

oh - I must have misunderstood the question

noisesmith16:02:18

actually, if the java code is being called from clojure, resolving *out* doesn't get the root binding, it gets the dynamic binding

noisesmith16:02:54

as long as you didn't do something like call the Thread constructor and lose your binding

frozenlock17:01:51

Is there a way to initialize InheritableThreadLocal in all the Clojure thread pool? (Such that it will be defined for future, pmap, etc.)

borkdude17:01:54

@frozenlock doesn't that already work?

user=> (def tl (proxy [java.lang.InheritableThreadLocal] [] (childValue [v] (.clone ^java.util.Map v))))
#'user/tl
user=> (.set tl (java.util.HashMap. {:a 1 :b 2}))
nil
user=> (.get tl)
{:a 1, :b 2}
user=> (.put (.get tl) :b 3)
2
user=> (.get tl)
{:a 1, :b 3}
user=> @(future (.put (.get tl) :b 4) (.get tl))
{:a 1, :b 4}
user=> (.get tl)
{:a 1, :b 3}

frozenlock17:01:44

Not if the thread used was already initialized/created. In that case (.get tl) will return nil.

frozenlock17:01:47

(pmap (fn [_] (.get tl)) (range 10)) can give inconsistent result.

frozenlock17:01:30

Perhaps there's a way to scrap all existing threads and start fresh, once the InheritableThreadLocal is defined?

potetm17:01:30

Why do you want that instead of, say, an atom?

frozenlock17:01:54

Long story short: I need an inheritable dynamic value. (IE capable of transparently moving between future, or pure java threads) I'm pretty much there... except for existing threads in which the InheritableThreadLocal isn't defined.

borkdude19:01:52

@frozenlock Can I ask you what you are using InheritableThreadLocal for? I recently discovered it and had a use case for it, but I wonder what other people are using this for.

frozenlock19:01:46

Sure. It's to accumulate some debug values that can ultimately be used inside UncaughtExceptionHandler.

frozenlock19:01:30

(context 1 .... (context 2 .... (context 3... BOOM))) <---- exception handler should be able to see the 3 contexts.

frozenlock19:01:39

What was yours?

borkdude22:01:43

thanks for sharing!

Alex Miller (Clojure team)18:01:30

You can set your own thread pool to use

Alex Miller (Clojure team)18:01:20

And the send-off equivalent (which future uses)

Alex Miller (Clojure team)18:01:06

I would consider these hostile in a library, but ok in an app

frozenlock18:01:17

Ah, it might be what I need. Thank you!

Hagenek20:01:19

Quick question for Vs code and Calva users. How do you stop evaluating when your functions enters an infinite loop?

Hagenek20:01:55

Tried Ctrl-Alt-C Ctrl-Alt-D, but that does not seem to do the trick. (Should stop evaluations).

seancorfield20:01:09

@USMLDU9BR FYI, there's a #calva channel where you might get answers faster for Calva-specific questions in future.

Hagenek20:01:36

Ahh great, thanks 😃 Ill go there instead

pez20:01:14

For anyone reading it here. There's a command in Calva for this. Not at a computer right now, but something like Interrupt running evaluations.

pez20:01:15

Ah, and that is the command you tried. Could also be that you have lots of printing in that runaway loop. It's an issue we yet have to fix. Interrupt does not stop the queued printing.

Hagenek20:01:37

:thumbsup: At least I found why it was entering an infinite loop now

metal 3