This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-02-21
Channels
- # arachne (1)
- # aws-lambda (50)
- # beginners (10)
- # boot (59)
- # capetown (4)
- # cider (9)
- # cljsjs (27)
- # clojure (249)
- # clojure-berlin (8)
- # clojure-finland (7)
- # clojure-germany (1)
- # clojure-italy (6)
- # clojure-nl (7)
- # clojure-russia (91)
- # clojure-spec (100)
- # clojure-uk (61)
- # clojureremote (2)
- # clojurescript (171)
- # core-async (11)
- # cursive (31)
- # data-science (1)
- # datascript (2)
- # datomic (11)
- # dirac (2)
- # emacs (16)
- # events (1)
- # hoplon (142)
- # juxt (4)
- # lein-figwheel (9)
- # leiningen (10)
- # luminus (7)
- # lumo (44)
- # mount (3)
- # off-topic (150)
- # om (18)
- # onyx (5)
- # perun (12)
- # planck (12)
- # protorepl (13)
- # re-frame (28)
- # reagent (8)
- # ring (1)
- # ring-swagger (10)
- # spacemacs (2)
- # specter (11)
- # sql (14)
- # untangled (99)
- # vim (18)
- # yada (2)
does someone know why specifying channel with 1 slot makes a difference to why a return value from channel is printed or not?
user> (require '[clojure.core.async :as async])
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/boolean?
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer, being replaced by: #'clojure.tools.analyzer.utils/boolean?
WARNING: bounded-count already refers to: #'clojure.core/bounded-count in namespace: clojure.core.async, being replaced by: #'clojure.core.async/bounded-count
nil
user> (async/go (let [c (async/chan)] (async/>! c 666) (println (async/<! c ))))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x3136af71 "clojure.core.async.impl.channels.ManyToManyChannel@3136af71"]
user> (async/go (let [c (async/chan)] (async/>! c 666) (prn (async/<! c ))))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x7636fd32 "clojure.core.async.impl.channels.ManyToManyChannel@7636fd32"]
user> (async/go (let [c (async/chan 1)] (async/>! c 666) (prn (async/<! c ))))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x7dcccbb6 "clojure.core.async.impl.channels.ManyToManyChannel@7dcccbb6"]
user> 666
user> (async/go (let [c (async/chan 1)] (async/>! c 666) (prn (async/<! c ))))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x5a8f3fa1 "clojure.core.async.impl.channels.ManyToManyChannel@5a8f3fa1"]
user> 666
user>
@hlolli If the channel is unbuffered … (chan)
… then a >!
or >!!
will park or block, because there are no takers. You need a buffer, a place to put the value, in order to not block/park. So, your print statements are never being executed until you buffer the channel and the >!
succeeds
@joshjones doesn't a (chan)
default to 1 buffer slot? Confused.
When you say “the return value from a channel”, since you are using go
blocks, understand that the result of a go
block is an implicit channel that contains the result of the body of the go
block. This is why every value is a channel, in your example, regardless of whether something prints or not.
ah ok ok, so >! is a blocking put, and it's actually not not printing but waiting forever for something to take the value. Ok makes sense.
using a future
so it won’t hang your repl:
(future
(let [c (chan)]
(println "about to put...")
(async/>!! c 42)
(println "won't print...")))
(let [c (chan)]
(println "about to put...")
(thread
(async/>!! c 42))
(println "just performed a put...")
(<!! c))
but then I wonder why a buffer of 1 doesn't block, ok then it's a buffer, a nature a buffer. Yes, all clear to me now. I often print from channels, but then it's always from one go macro to another. So it succeeds without buffer.
>!
is a “parking put” … it blocks if there are no takers and the buffer is 0 or full. The difference is that the thread context will be saved, and the thread can be used to execute other code in the meantime. >!!
is a true “blocking put” and the thread will not be reused.
thanks @joshjones