This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-19
Channels
- # ai (4)
- # announcements (1)
- # babashka (6)
- # beginners (31)
- # biff (1)
- # calva (11)
- # cider (9)
- # clerk (6)
- # clojure (40)
- # clojure-europe (49)
- # clojure-nl (1)
- # clojure-norway (30)
- # clojurescript (17)
- # conjure (1)
- # core-async (2)
- # datalevin (28)
- # emacs (1)
- # events (4)
- # fulcro (7)
- # gratitude (1)
- # guix (4)
- # hyperfiddle (19)
- # juxt (10)
- # luminus (4)
- # malli (4)
- # missionary (11)
- # nbb (3)
- # pedestal (7)
- # reagent (27)
- # reitit (2)
- # releases (1)
- # shadow-cljs (32)
- # tools-deps (6)
- # xtdb (5)
Hello, I am a beginner and excited to use ClojureScript to make cool apps! I am running into an error where the REPL can't find my functions:
#object[TypeError TypeError: Cannot read properties of undefined (reading 'call')]
(<NO_SOURCE_FILE>)
After a bit of playing around, I realized that the REPL doesn't register variables that aren't called. Is this true? Is there a way to disable this while developing? I feel like it's obvious that when I have written a function I would wan to run it in the REPL a few times even if I haven't gotten around to calling it just yet.you don't need to call the function just require the namespace that contains it at some point
(you can require it manually in the REPL, but also require it in your dev entry point so that it's always loaded)
I just learned a lesson that might be worth sharing with other beginners like me:
In my code, I was using map
and pmap
for side-effecting things like this:
(defn clone-all-repos
[repos]
(->> repos
(extract-key :sshUrl)
(pmap clone-repo)))
And this was seemingly working because the REPL was realizing the collection for me while developing, meaning all repos would be cloned in this case. However, when running my code outside of the REPL, only the first 32 repos would be cloned because pmap
is "semi-lazy" and only processes the first chunk of 32 items in the collection.
To process the whole collection eagerly, I had to add doall
:
(defn clone-all-repos
[repos]
(->> repos
(extract-key :sshUrl)
(pmap clone-repo)
(doall)))
But my friends in #C061XGG1W recommended using doseq
instead for "imperative stuff with side effects," so I'm changing my code.doseq
is great when parallelism is not needed and sequential will do fine. Here’s a snippet using core.async to bring arbitrary parallelism to a task like this one, without using pmap:
(let [dest-ch (a/chan)
parallelism 8]
(a/pipeline-blocking parallelism
dest-ch
(map clone-repo)
(a/to-chan! (extract-key :sshUrl repos))
dest-ch))
This returns a channel that will contain the results of clone-repo in the same order as repos
. It is important to consume this channel for the internal workers to have space to put new results and continue to do work.
edit: fixed bugI had this problem, check out @U7ERLH6JX response https://clojurians.slack.com/archives/C053AK3F9/p1685473873556869 I ended up using virtual threads in my problem
Here is what it looks like with doseq
:
(defn clone-all-repos
[repos]
(doseq [url (extract-key :sshUrl repos)]
(clone-repo url)))
This is true; this particular function is significantly slower without parallelization, because it clones each repo one at a time.
Cool, thanks for the tip! That might get too advanced for me at this stage, and I'm not sure whether it would work in a Babashka script, but I'll save it for later!
@U01PE7630AC, Any particular reason not use clojure/async for paralism ?
I was exploring https://github.com/http-kit/http-kit , if I use (http/get ......)
with multiple user request and deref
the response, Does it block the main thread until I get the result? My fear is that, If large number of request comes it might block all the thread and leads to bad performance,
deref'ing will block the thread on which deref was called. deref takes a timeout if you want to avoid blocking for a long time, and an http-kit client request takes a timeout if you want to give up on getting a response after some amount of time. As far as concerns about blocking all the threads, requests could be batched, or use core.async's pipeline-async function, or one of any number of strategies... it's probably mainly a question of design based on your specific context.
Thanks for your response, I am thinking of calling it using async.chan and derefer the result , will that be a good approach ? because async/go will create light weight threads
While working on a project with reitit and reading the docs I come across a function definition like this (fn [{::r/keys [router]}] ...)
there is some destructuring going on but with what I would describe as with extended/custom syntax. Can someone point me to some documentation on how this works? How can I extend the syntax myself if I wanted to?
it's destructing values from a map with namespaced keys like {:reitit.core/router <something> ...}
where the alias r
refers to reitit.core
(or some similar) namespace
here's a nice discussion highlighting the various ways you can destructure such maps https://clojureverse.org/t/poll-destructuring-namespaced-keywords/1388
Can someone help me resolve an error with building a project? I'm running clj -A:build uber
and getting this error:
Error building classpath. Library io.github.clojure/tools.build has missing :sha in coordinate.
I have this alias in my deps.edn
:
:aliases
:build {:replace-deps {io.github.clojure/tools.build {:git/tag "v0.9.4" :git/sha "76b78fe"}}
:ns-default build}}
And I verified that I'm using the latest tag and the correct commit sha.you are using an old version of the Clojure cli, before :git/sha was added, so you update to the latest
Ah. Is there a CLI command to update it? If not, do I need to uninstall the current version before installing the new one?
depends which OS and method of install you used
I'm using WSL and unfortunately, I don't remember how I installed it. Is there a way to check that?
If you used the Linux installer, should be able to just install the new version following that script