Fork me on GitHub
Ory Band12:12:46

Hi. is there a way to check if I am inside a core.async go block? I'm writing a macro that calls <! but i want to fail before reaching the line calling <!

Ben Sless13:12:55

If you're doing it in a macro, then <! won't compile if it's not in a go block anyway. But I have to ask, why?

Ory Band13:12:36

i understand it won't compile, my problem is that it will raise the error too late for me. i'd like to write a macro that will fail immediately if it is not in a go block, similar to calling <! directly i am writing a macro that does two things: 1. send an async http request. the http-send fn returns a channel 2. take from that channel using <!. if my macro is called outside of a go block, it will fail on 2. i want it to fail before 1 occurs i.e. before sending the http request

Ben Sless13:12:39

Roughly, something like

(defmacro send!
  `(let [p# (a/promise-chan)]
     (http/send req (fn [resp#] (a/put! p# resp#)))
     (a/<! p#)))

Ory Band13:12:45

but the send will still occur instead of not execute and crash

Ory Band13:12:51

i want to avoid the send

Ben Sless14:12:49

It won't. This macro won't even compile (not talking about run, but compile) if it's not in a go block.

Ben Sless14:12:22

but I would just return a channel instead of hiding it behind magic

Ben Sless14:12:52

Having had to deal with something very similar just a few days ago =\

Ory Band14:12:14

i don't understand why

Ory Band14:12:34

that is, why won't it compile

Ory Band14:12:08

the stage where there's a put/take come after the send

Ben Sless14:12:42

ach, my bad, <! is defined as a function and not a macro, it will only throw at runtime

Ben Sless14:12:08

which brings us back to my other recommendation anyway, use a function and not a macro, return a channel and handle it in the go block

Ben Sless14:12:46

Which, when you say "I have a macro that does two things", should raise a flag - why not compose two separate things?

Ory Band14:12:47

the first stage is happening in a different function that sends http and async puts on a chan and returns that chan

Ben Sless14:12:53

Use some function like this to turn an async function to a function which returns a channel:

(defn afn->p
  (fn [ctx]
    (let [p (a/promise-chan)]
      (af ctx (fn [result] (a/put! p result)))

Ben Sless14:12:30

So just work with a bare channel. In this context you should treat it like a promise or a completion stage

Ory Band14:12:20

thanks. i was hoping theres a way around that 😕 i'm writing a helper function to on board code which doesn't yet support async.core channels

Ben Sless14:12:34

Can you elaborate a bit? core.async is great but it's not necessarily a fit in every situation. Why should code support it to begin with? Shouldn't it be generic and be open to adaptation by building an abstraction layer / good separation of existing layers?


<!! will take from a channel in a blocking way. That might be what you want. But to @UK0810AQ2’s point - core.async isn’t necessarily a fit in every situation

Ory Band19:12:27

Hi. yes, i will do that tomorrow, sorry for long delay

Ory Band19:12:47

thank you for all the assistance

Muhammad Hamza Chippa20:12:29

(clojure.string/split "EURJPY.COMP" #".") this command is not splitting the string on the basis of "." how can I split it ?

Cora (she/her)20:12:02

. matches any character in regex

🙌 1
Cora (she/her)20:12:18

you want #"\."

🙌 1

Am I crazy for thinking (apply juxt) should work on a list, just like it does with a vector?


it works fine:

((apply juxt (list true? false? string?)) "foo")


the problem is that '(true? false? string?) doesn’t evaluate to what you think it does. evaluate it in the repl


a hint, what is 'true? ?


Ahh I see, it's creating a list of symbols… I guess I need to refresh my memory on how quoting works


Thank you!


you’re welcome

Chad kennedy22:12:08

It's symbolsturtles all the way down 😉