This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-07
Channels
- # announcements (32)
- # asami (11)
- # babashka (5)
- # babashka-sci-dev (4)
- # beginners (65)
- # biff (11)
- # calva (35)
- # clerk (2)
- # clj-kondo (14)
- # clj-on-windows (4)
- # clojars (4)
- # clojure (122)
- # clojure-canada (1)
- # clojure-europe (31)
- # clojure-italy (6)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-spec (3)
- # clojure-uk (2)
- # clojurescript (3)
- # core-async (7)
- # core-logic (1)
- # data-science (13)
- # datalog (3)
- # datavis (3)
- # datomic (15)
- # deps-new (4)
- # emacs (34)
- # figwheel-main (1)
- # fulcro (1)
- # funcool (1)
- # holy-lambda (10)
- # lsp (41)
- # malli (24)
- # membrane (5)
- # midje (1)
- # off-topic (5)
- # polylith (3)
- # proletarian (6)
- # re-frame (6)
- # reitit (6)
- # remote-jobs (4)
- # sci (1)
- # shadow-cljs (96)
- # sql (31)
- # testing (23)
- # xtdb (49)
I'm confused about why something I'm doing fails with (take!)
but works fine with (go (<! ...))
.
Here's what I'm doing:
(require '[clojure.core.async :refer [go put! take! chan]])
; f is a function that will call itself asyncronously. In real usage, the put!
; is happening else-where and we want to free up the thread f is running on while we
; wait for that put.
; I know that this example can be represented as a loop rather than as a recursion,
; that's not the point.
; If you run this, it will never print "done."
(defn f [v]
(if (< v 100)
(let [c (chan)]
(put! c (inc v))
(take! c f false))
(println "done")))
(f 0)
; => nil
; If you re-write f as follows however, it works. I want to understand what the difference
; between the two is:
(defn f' [v]
(if (< v 100)
(let [c (chan)]
(put! c (inc v))
(go (f' (<! c))))
(println "done")))
(f' 0)
; => clojure.core.async.impl....
; done
I’m using vscode and on the first example it prints done on the terminal, while the second example prints done on the REPL output
I think it might be how the go is being dispatched to the executor, that captures thread bindings (potentially the out ?) , in contrast to how the take! callback is dispatched (`(dispatch/run #(fn1 val))`).
Hmmm, I stupidly didn't think to check the terminal :face_palm: What initially threw me off is the debugger. If you run if for f, it behaves really strangely.
The thread binding explanation sounds plausible