This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-12-17
Channels
- # adventofcode (56)
- # announcements (1)
- # aws (6)
- # beginners (127)
- # bristol-clojurians (1)
- # calva (29)
- # cider (7)
- # clj-kondo (37)
- # cljdoc (20)
- # cljsrn (7)
- # clojure (159)
- # clojure-europe (67)
- # clojure-italy (23)
- # clojure-nl (4)
- # clojure-provo (3)
- # clojure-uk (18)
- # clojurescript (19)
- # code-reviews (59)
- # community-development (105)
- # conjure (6)
- # core-async (16)
- # core-logic (1)
- # cursive (21)
- # datomic (19)
- # defnpodcast (1)
- # emacs (8)
- # events (2)
- # fulcro (71)
- # graalvm (23)
- # jobs-discuss (1)
- # kaocha (5)
- # luminus (5)
- # meander (16)
- # nrepl (32)
- # off-topic (6)
- # pathom (159)
- # pedestal (3)
- # reagent (14)
- # reitit (8)
- # reveal (12)
- # rewrite-clj (9)
- # shadow-cljs (169)
- # spacemacs (16)
- # specter (2)
- # sql (19)
- # tools-deps (36)
- # vim (6)
You want to take an existing library you are using in your Clojure code, and redefine a function inside of that library?
You could do this by changing to the namespace where that function is defined, e.g. (in-ns 'that.library.namespace)
Then do (defn fn-i-want-to-redefine [arg1 arg2 ...] ...)
Then (in-ns 'user)
if you were in a REPL, to switch back to the user
namespace that one often works in, or switch to any other namespace you want. Or stay in the namespace that.library.namespace
if you really want to.
That will redefine the function in the running JVM -- it will not change the source code of the library that will be loaded if you quit that JVM and start another one.
(defn splitSum []
(let [part1 (future (sum 0 (/ 1e7 2)))
part2 (future (sum (/ 1e7 2) 1e7))]
(+ @part1 @part2)))
(time splitSum)
time
times an expression, so you are timing how long it takes to retrieve(?) splitSum
then I get this error on this code :
(defn splitSum []
(let [part1 (future (sum 0 (/ 1e7 2)))
part2 (future (sum (/ 1e7 2) 1e7))]
(+ @part1 @part2)))
(time (splitSum))
Caused by: java.lang.ClassCastException: class clojure.lang.Delay cannot be cast to class java.lang.Number (clojure.lang.Delay is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')
at clojure.lang.Numbers.add(Numbers.java:153)
at ground_up.chapter6$splitSum.invokeStatic(chapter6.clj:37)
at ground_up.chapter6$splitSum.invoke(chapter6.clj:34)
at ground_up.chapter6$fn__197.invokeStatic(chapter6.clj:39)
at ground_up.chapter6$fn__197.invoke(chapter6.clj:39)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3702)
that means that sum
returned a delay, not a number
[SOLVED] Hello, I have an issue I can't resolve via googling with the Clojure Koans 03_lists.clj : See line 36-39 in the screenshot below. Regardless of what I type in the blank, the terminal running koan returns "Unable to resolve symbol: catch in this context" .
This works for me just fine:
"But watch out if you try to pop nothing"
(= "No dice!" (try
(pop '())
(catch IllegalStateException e
"No dice!")))
"The rest of nothing isn't so strict"
(= () (try
(rest '())
(catch IllegalStateException e
"No dice!"))))
I cloned this repo: https://github.com/functional-koans/clojure-koans
Are you using the same one?
How do you run it? (via lein koan run
?)Yes, I'm using the same repo. I also use Paredit, could it be that paredit changed the content of the koan?
Trying to set up vim fireplace and I'm getting this error https://github.com/tpope/vim-fireplace/issues/372
I've RTFM but the issue isn't mentioned there
Fireplace is working perfectly for clj
files though
@signup867 you may get more help in the #vim channel
ahh, thanks
Hi, i've this request grpc ^io.grpc.example.AccountsRequest request
and I want read metadata like token from headers. Someone knows how I can do it?
You could use apply
.
well numbers in a range can also be added with (first + last) * n /2 :)
(* (+ 0 9) (/ 10 2))
== (reduce + (range 10))
thanks, but I do not think that is the purpose of this challenge
Instead of using reduce, store the sum in an atom and use two futures to add each number from the lower and upper range to that atom
swap! needs a function, a number isn't a function
I'd like to learn more about how the CLJS compiler(s) work. Specifically, how do the cljc bits make it to both the java and the JS side? Do library authors have to publish both an npm package and on Clojars to make the library available in CLJS?
Some libraries publish .cljc source files packaged inside of a JAR file to Clojars, I believe, and that same JAR file can be used from ClojureScript, I think? Don't trust my answer since I rarely use ClojureScript, but I believe several libraries are published to Clojars that way
e.g. medley is a small library with a single .cljc file published as a JAR on Clojars: https://clojars.org/medley
Hi everyone, a beginner question, is some kind of convention using the ! naming a function like add-todo! ?
often means a side-effecting function. in this case would store the "todo" in some mutable storage, be it a db, some client side db, etc.
Where can I find examples of tools.cli using the :in-order
option? I’m having a hard time figuring out how to use it correctly.
stilll feel like a really beginner
(defn atomSum []
(let [atom (atom 0)
part1 (future (swap! atom (apply + range(0 (/ 1e7 2)))))
part2 (future (swap! atom (apply + range((/ 1e7 2) 1e7))))]
(deref atom)))
(atomSum)
Hi, depending on your IDE, the procedure is quite different, but to "debug", I use to 1) reread carrefully 2) decompose the function in smaller ones and run a test function for each 3) insert some println 4) use the inspector features 5) I even found some 6) I discovered dotrace which may help. Personnaly I usually stop @ 2, sometime 3. Teach him how to fish and you feed him for his life time 😁
ok, the best experience is to start a repl, connect to it with vs-code, launch "evaluate current form"
You have range
on the wrong side of the (
deref
those futures too
still not the right answer
(defn atomSum []
(let [atom (atom 0)
part1 (deref (future (swap! atom (apply + (range 0 (/ 1e7 2))))))
part2 (deref (future (swap! atom (apply + (range 0 (/ 1e7 2))))))]
(deref atom)))
swap! takes a function, apply is not returning a function
perhaps you want (swap! atom + (apply ...))
(defn atomSum []
(let [atom (atom 0)
part1 (deref (future (swap! atom + (apply + (range 0 (/ 1e7 2))))))
part2 (deref (future (swap! atom + (apply + (range 0 (/ 1e7 2))))))]
(deref atom)))
(atomSum)
right, the only thing they do is make sure you don't deref the atom at the end before the futures are done executing
well, it does expose a problem with the code - the futures don't do anything useful because you don't create one until the other returns
(defn atom-sum
[]
(let [a (atom 0)
part1 (future (swap! a + (apply + (range (/ 1e7 2)))))
part2 (future (swap! a + (apply + (range (/ 1e7 2)))))]
@part1
@part2
@a))
that will take ~half the time as yours because the sums happen in parallel, instead of one at a time, that's why we use futures
; Instead of using reduce, store the sum in an atom and use two futures to add
; each number from the lower and upper range to that atom. Wait for both
; futures to complete using deref, then check that the atom contains the right
; number. Is this technique faster or slower than reduce? Why do you think
; that might be?
yeah - if you create both futures, then deref, it's faster (if you have multiple CPUs), if not it's slightly slower
this is also working
(defn atomSum []
(let [atom (atom 0)
part1 (future (swap! atom + (apply + (range 0 (/ 1e7 2)))))
part2 (future (swap! atom + (apply + (range 0 (/ 1e7 2)))))]
(deref part1)
(deref part2)
(deref atom)))
the code now is something slower then this one
(defn sum3
[from to]
(reduce + (range from to)))
(defn splitSum []
(let [part1 (future (sum3 0 (/ 1e7 2)))
part2 (future (sum3 (/ 1e7 2) 1e7))]
(+ @part1 @part2)))
(time (splitSum))
clj::ground-up.chapter6=>
"Elapsed time: 501.8355 msecs"
24999995000000
clj::ground-up.chapter6=>
#'ground-up.chapter6/sum3
clj::ground-up.chapter6=>
#'ground-up.chapter6/splitSum
p.chapter6=>
"Elapsed time: 8clj::ground-up.chapter6=>
"Elapsed time: 466.1117 msecs"
4.9999995E13
clj::ground-u87.6055 msecs"
49999995000000
In AOC I struggled to do something that feels like it should be quite simple: For a set of integers, return a sequence of n-tuples with every combination of those integers. So for integers 0 and 1 looking for an 2-tuple, you would get [[0 0] [0 1] [1 0] [1 1]]
etc.
I ended up doing something heinous like (combo/permuted-combinations (apply concat [(repeat 3 0) (repeat 3 1)]) 3)
- did I miss something obvious here?
(NB: I know now that for the specific case where integers are 0 and 1 I'm effectively looking for the binary numbers between 0 and 2^n, but am looking for something more general)
=> (combo/selections [0 1] 2)
((0 0) (0 1) (1 0) (1 1))
but I think people usually try to solve AOC without libraries, not sure if they are allowedThanks, that’s what I’m looking for. And AOC takes enough of my time without having to implement my own combinatorics 😀
@U751SU53R I am not aware of that rule. Thx for the fn.
I recently pick up Clojure and I'm really liking it so far, which is why I wanted to join the Clojure slack group. I hope I can learn from everyone and contribute (eventually)
Thanks! actually on 2nd thoughts, I'm gonna rejoin with my personal email, feels like using work email for this is not a great idea haha
@tuananh.le Let me (or any other Admin) know if you want that work-email-based account deactivating once you are signed up with your personal email.
Hey @U04V70XH6, nice to meet you! I will definitely let you know once I set up my personal email so you can deactivate this one
No problem. Feel free to DM me any time if you need activation/deactivation on any of your email accounts here on Clojurians!
is it possible to edit your email address without creating a new account? (no idea, but sounds possible-ish)
Not as far as I know @dpsutton
(Slack is designed for companies so I'm sure they wouldn't want folks switching company communications to a personal account)
fair enough. slack logins aren't the best in the world. i have like 9 username/passwords in my password manager that at one point all were entitled "Slack" and took a while for me to disambiguate
(and we can continue discussions re: Slack in #community-development if we need to, not in #beginners)
I'm actually trying edit my email address rightnow, as far as I know, that seems to be an option on slack
I'm having some trouble joining clojurian slack with my personal email. Do I need some sort of invitation to join?
You should be able to go to http://clojurians.net and enter your personal email address and get an invite @tuananh.le
I'm pretty sure you cannot edit/change your email address in Slack -- for security reasons since Slack is designed for companies and they would want the security of controlling email addresses used for access.
When writing clojure i find myself doing lots calls to map, reduce, filter, etc all in different functions. In a non-functional language i'd typically do all of these checks in one iteration of a loop. I'm concerned about performance regarding this approach, how much overhead does the actual iteration over sequences add?
For example, the way that i'm building a map in doc->candidates:
(ns the-great-escape.core
(:require
[clj-http.client :as client]
[hickory.core :as html]
[hickory.select :as s]
[clojure.string :as string]
[lambdaisland.uri :refer [uri]])
(:gen-class))
(defn doc->hickory [doc]
(-> (html/parse doc)
(html/as-hickory)))
(defn fetch-and-parse-page [url]
(-> (client/get url
{:cookie-policy :standard
:redirect-strategy :none})
(:body)
(doc->hickory)))
(defn extract-asset-tags [body]
(s/select (s/or
(s/attr :href)
(s/attr :src))
body))
(defn extract-href-urls [tags]
(map #(get-in %1 [:attrs :href]) tags))
(defn extract-src-urls [tags]
(map #(get-in %1 [:attrs :src]) tags))
(defn extract-asset-urls [tags]
(->> (extract-href-urls tags)
(filter #(not (nil? %1)))))
(defn parse-urls [urls]
(map uri urls))
(defn local-asset? [base-domain {:keys [host]}]
(or (nil? host) (= base-domain host)))
(defn filter-local-paths [base-domain parsed-urls]
(->> (filter (partial local-asset? base-domain) parsed-urls)
(map :path)
(filter #(not (nil? %1)))
))
(defn url->parts-map [url]
(let [parts (string/split url #"/")]
{:dir (str "/" (second parts))
:path (str "/" (string/join "/" (drop 2 parts)))}))
(defn get-unique-dirs [parts-map]
(map #(first (val %1)) (group-by :dir parts-map)))
(defn filter-bad-traversals [parts-map]
(filter #(and (not= (:dir %1) "/") (not= (:path %1) "/")) parts-map))
(defn build-original-url [base-url parts-map]
(str (assoc base-url :path (str (:dir parts-map) (:path parts-map)))))
(defn build-traversal-url [base-url parts-map]
(str (assoc base-url :path (str (:dir parts-map) ".." (:dir parts-map) (:path parts-map)))))
(defn request-and-hash [url]
(println url)
(-> (client/get url)
(:body)
(hash)))
(defn doc->candidates [base-domain doc]
(->> (extract-asset-tags doc)
(extract-asset-urls)
(parse-urls)
(filter-local-paths base-domain)
(map url->parts-map)
(get-unique-dirs)
(filter-bad-traversals)))
if you're worried about performance, you can use the transducer version of all of those operations (map, filter, etc), but I wouldn't worry too much about it for most use cases
Ah cool will look into that. Not massively worried about perfomance as network io on the http requests will be the main bottleneck, but scanning 1 million+ hosts it adds up over time
Now to try out core.async
So I'm using the clj-http
libraries async http get to try and dump the response into a core.async
channel and then alter an atom called state
based on that response and also return the response, but when I call this get-listings
function all I get back is #object[cljs.core.async.impl.channels.ManyToManyChannel]
and I'm not sure what I'm doing wrong
so my guess is it did fail to compile, but you have some previous version of get-listings defined in your repl, and that is what you are calling
ic, I guess I don't really need do use channels here if I just dump the http response into the atom in the callback function
I dunno, I mean, why don't you just write a little program that runs in a loop, pulling data from the web api, then doing something with it
I need the data to render some components so I've been using a reagent atom for that, but I thought that I could maybe just return the data directly by using core.async
that maybe why the compiler didn't throw an error about that invalid use of >!
, the cljs side of core.async needs some love
I was using cljs-http
but wanted to switch to clj-http
. Is it not supported on cljs?
if by clj-http you mean https://github.com/dakrone/clj-http the library which is a wrapper around the apache java http client, then I very much doubt it (although I haven't been paying too much attention to clj-http in recent years, so I suppose it is possible it somehow sprouted such a thing)
if you mean something else, then it is extremely tedious of someone to have used that same name for a cljs http client
https://github.com/r0man/cljs-http/blob/master/test/cljs_http/client_test.cljs has some examples of how to use it if you're interested