Fork me on GitHub
#beginners
<
2023-06-19
>
Nim Sadeh04:06:49

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.

rolt07:06:18

you don't need to call the function just require the namespace that contains it at some point

rolt07:06:08

(you can require it manually in the REPL, but also require it in your dev entry point so that it's always loaded)

rolt07:06:58

I'm assuming you're using shadow cljs ou figwheel main for hot reload

leifericf11:06:41

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.

thanks2 4
bortexz11:06:20

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 bug

👀 2
Aziz Aldawood11:06:13

I had this problem, check out @U7ERLH6JX response https://clojurians.slack.com/archives/C053AK3F9/p1685473873556869 I ended up using virtual threads in my problem

👍 2
leifericf11:06:35

Here is what it looks like with doseq:

(defn clone-all-repos
  [repos]
  (doseq [url (extract-key :sshUrl repos)]
    (clone-repo url)))

leifericf11:06:04

This is true; this particular function is significantly slower without parallelization, because it clones each repo one at a time.

emilaasa12:06:22

I've had success using claypoole, https://github.com/clj-commons/claypoole

👀 2
emilaasa12:06:11

Here you could use pdoseq which I think will do what you want.

leifericf12:06:52

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!

Kishor Pandey13:06:16

@U01PE7630AC, Any particular reason not use clojure/async for paralism ?

leifericf13:06:35

@U05AH1BJNQ6 No good reason other than I haven't learned about that yet 🙂

😁 2
Kishor Pandey12:06:51

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,

Bob B13:06:55

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.

Kishor Pandey13:06:11

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

Bob B13:06:00

I'd say it really depends on context

rickheere13:06:37

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?

lassemaatta14:06:48

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

lassemaatta14:06:34

here's a nice discussion highlighting the various ways you can destructure such maps https://clojureverse.org/t/poll-destructuring-namespaced-keywords/1388

rickheere14:06:21

Aah nice, yeah now I understand. Thank you so much!

Evgeniy18:06:11

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.

Alex Miller (Clojure team)18:06:17

you are using an old version of the Clojure cli, before :git/sha was added, so you update to the latest

Evgeniy18:06:13

Ah. Is there a CLI command to update it? If not, do I need to uninstall the current version before installing the new one?

Alex Miller (Clojure team)18:06:22

depends which OS and method of install you used

Evgeniy18:06:38

I'm using WSL and unfortunately, I don't remember how I installed it. Is there a way to check that?

Alex Miller (Clojure team)19:06:55

If you used the Linux installer, should be able to just install the new version following that script

Evgeniy19:06:54

I'll try that. Thanks for your help!