5 ms·
"because it uses macros, the suspendable constructs are limited to the scope of a single code block, i.e. a function running in a suspendable block cannot call
by donjigweed 13y ago
"because it uses macros, the suspendable constructs are limited to the scope of a single code block, i.e. a function running in a suspendable block cannot call another blocking function; all blocking must be performed at the topmost function. It’s because of the second limitation that these constructs aren’t true lightweight threads, as threads must be able to block at a any call-stack depth"
Can you elaborate on this a bit? Let's say I have a function called 'fetch-url' which takes a core.async channel as an argument and makes a non-blocking http request (say, using http-kit), and in the callback handler i put the result onto the channel. If I'm in some other function, in which whose body I open a core.async go block and call fetch-url from within that go block, everything is still asynchronous is it not?
- pron 13y agoIf you're using callbacks at all, then you're not blocking. The main advantage threads (and lightweight threads) have is that they can block. What you can't do is this: (defn foo [ch] (go (bar ch))) (defn bar [ch] (<! ch)) foo starts a go block which calls bar, which then blocks on the channel. For threads that's ok: (defn foo [ch] (thread ; not sure about syntax here (bar ch))) (defn bar [ch] (<!! ch)) So a function running in a thread can call another function that blocks. A go block can't, that's why go blocks aren't lightweight threads. BTW, in Pulsar's implementation of core.async, the first example is ok, too.