This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-10
Channels
- # announcements (6)
- # architecture (2)
- # babashka (30)
- # beginners (90)
- # calva (21)
- # cider (22)
- # clj-kondo (27)
- # cljs-dev (7)
- # clojure (132)
- # clojure-europe (51)
- # clojure-nl (12)
- # clojure-norway (3)
- # clojure-spec (3)
- # clojure-uk (5)
- # clojurescript (69)
- # cloverage (9)
- # conjure (5)
- # core-async (54)
- # cursive (14)
- # datomic (34)
- # emacs (7)
- # fulcro (10)
- # graalvm (40)
- # graalvm-mobile (2)
- # gratitude (2)
- # improve-getting-started (1)
- # introduce-yourself (1)
- # jobs-discuss (61)
- # leiningen (5)
- # malli (6)
- # off-topic (59)
- # pathom (11)
- # polylith (38)
- # reagent (3)
- # reitit (3)
- # rewrite-clj (3)
- # shadow-cljs (53)
- # tools-build (35)
- # transit (8)
- # vim (62)
- # web-security (26)
- # xtdb (4)
Hi everyone
Since into
requires the input channel to be closed before it produces a result, and to-chan
does indeed close the channel that it creates, the result is as expected.
(<!! (into [] (to-chan (range 10))))
;; => [0 1 2 3 4 5 6 7 8 9]
On the other hand, closing c
explicitly produces a result that I didn't expect:
(def c (chan))
(onto-chan c (range 10) false)
(close! c)
(<!! (into [] c))
;; => [0]
If c
has a buffer of length at least 10, then the result is the same as that above. What am I misunderstanding here?I guess that to-chan
creates a buffer of the length required by the collection, whereas the pending puts onto c
are discarded. I would then expect the second variant to produce [].
(chan)
acts as a rendezvous point so one adding a value (`0`) onto it parks, then you close it, then you read from it, which picks up the parked 0
, and then it's a closed channel.
Thanks Sean.
If you use (chan 1)
, you actually get two values out of it:
user=> (def c (chan 1))
#_=> (onto-chan c (range 10) false)
#_=> (close! c)
#_=> (<!! (into [] c))
...
[0 1]
(for the same reason)
Got you - subtle stuff!
core.async
is tricky.
I'm still a hobbyist and haven't used it in any project yet, but I'm really excited by its potential.
onto-chan pours some values into an existing channel. Your call to onto-chan returns immediately and the pouring happens in the background (subject to the flow of the channel that you're pouring into) the close! call closes the destination channel of that background pouring process.
since you used a rendezvous chan (an unbuffered channel), the pouring process is going to be driven by the takers on the destination channel the 3 calls to 1) launch the background pouring (onto-chan), 2) close the channel, and 3) launch the async/into process - those call proceed rapidly in succession
This question was asked in the wrong channel and removed:
> in rich4clojure. I press the atl+enter key and the tests fun return nil. how can i know its pass or fail
Reposting it here to be able to provide an answer. 😃 I'm assuming this is a problem when running Rich4Clojure locally (as opposed to the GitPod option). The solution is to first load dev/repl.cljc
, to initialize the testing facility. It's mentioned here: https://github.com/PEZ/rich4clojure#on-your-machine
We (I think I can speak for the community here) really want to make it easier! We have a channel for it: #improve-getting-started Please don't hesitate to post there about what makes it hard for you and if you have ideas what would make it easier.
Have you found my https://calva.io/get-started-with-clojure/ attempt to help with this, btw?
Is there a core fn to change from [{:name "Foo" :value 1}, {:name "Bar" :value 2}]
to {"Foo": 1, "Bar": 2}
?
On my phone so haven't tested it but something like this should work:
(into {} (map (juxt :name :value) coll))
Hi fellow Clojurists, I’m struggling to understand how to compose predicates with the every-pred, especially how to explain why an execution error in thrown here:
user=>((every-pred even? integer?) 4.99)
; Execution error (IllegalArgumentException) at ghostly.core/eval7861 (form-init12829955687297635352.clj:100).
; Argument must be an integer: 4.99
you are doing it correctly. even?
is just a little picky. (even? 3.45)
throws an error that its argument must be an integer
In CojureScript, is it safe to use the namespace clojure.browser.dom
or should it be considered as implementation?
It's safe but I've rarely seen it use anywhere. It's a part of history now and no updates have been made to it.
I think it might be better to just use goog.dom
directly, but I would go a step further and say if you don't really care about compat with IE11 and stuff just directly use js/...
APIs.
https://github.com/clojure/clojurescript/blob/master/src/main/cljs/clojure/browser/dom.cljs
I would like to add a docstring to my multimethod. Are there conventions around this?
A multimethod has a single doc string, you can set with the defmulti that creates the multimethod
thank you, that answers my question
you can also make your own table of
{spec-kw-or-sym -> metadata}
and store whatever metadata you want
Another core.async
misunderstanding! map
is core.async/map
and the example is a modification of the documentation.
(defn inc-async
[num]
(let [ret (promise-chan)]
(go
(<! (timeout (rand-int 2000))) ;; Randomly sleep up to 2 seconds
(put! ret (inc num)))
ret))
(def a (atom nil))
(go
(let [v1 (inc-async 1)
v2 (inc-async 10)
v3 (inc-async 100)]
(reset! a (take! (map vector [v1 v2 v3]))))
Why does @a
return nil
?
What about using <!
?
Using <!
still returns nil
That's weird - I'm using Clojupyter, but it also failed in Calva.
I'll try a lein repl
Surely map
should block until all results are available?
Incorrect - still get nil
- trying lein repl now
Got you! Sounds good.
it's clearer for understanding to have the last statement of the go block be (<! (map ...)) then take from the go block (remember go blocks return a channel that yields their last expression)
That's great - thanks so much
oh - didn't know
I'm making slides in revealjs, and I want to do line-by-line animations. What's an idiomatic way to turn this:
[[:h2 "title"] [:p "some info"] [:li "an item"] [:li "another item"]]
into this?
[:section
[:section {:data-auto-animate ""} [:h2 "title"]]
[:section {:data-auto-animate ""} [:h2 "title"]
[:p "some info"]]
[:section {:data-auto-animate ""} [:h2 "title"]
[:p "some info"]
[:li "an item"]]
[:section {:data-auto-animate ""} [:h2 "title"]
[:p "some info"]
[:li "an item"]
[:li "another item"]]]
It's the "take 0, then take 1, then take 2" over and over that I am having trouble thinking of a function for(defn animate [title & items]
(for [index (range (count items))]
(concat [:section title] (take index items))))
hmmm(animate [:h2 "title"] [:p "2018"] [:li "23 employees"])
;; => ((:section {:data-auto-animate ""} [:h2 "title"]) (:section {:data-auto-animate ""} [:h2 "title"] [:p "2018"]))
those aren't vectors(defn animate [title & items]
[:section
(for [index (range (count items))]
(vec (concat [:section {:data-auto-animate ""} title] (take index items))))])
(animate [:h2 "title"] [:p "quote"] [:li "item"] [:li "another"])
;; => [:section ([:section {:data-auto-animate ""} [:h2 "title"]] [:section {:data-auto-animate ""} [:h2 "title"] [:p "quote"]] [:section {:data-auto-animate ""} [:h2 "title"] [:p "quote"] [:li "item"]])]
Maybe?
(defn animate [title & items]
(vec (concat [:section]
(for [index (range (count items))]
(vec (concat [:section {:data-auto-animate ""} title] (take index items)))))))
Curious how Clojure developers deal with lack of types? I am Curious about Clojure and have played with it, but not being able to get type-checking really crippled me Since I was blindly writing code without knowing if it was correct or not until I tried to run it Are there any tools/options for this?
While @U04V70XH6 is quite correct about running code (even just snippets of it) as you go, personally, I find types are useful, even if it’s just for documentation. Many people like spec, though I haven’t been comfortable with it (for multiple reasons). I suggest looking at Malli