Hi how can I rewrite some function from an lib ?
You want to take an existing library you are using in your Clojure code, and redefine a function inside of that library?
Yes, I do.
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 ...] ...)
Thanks for help me
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.
Why do I get here a function instead of the result
(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
You’d probably want to call splitSum: (time (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)
[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
?)(try)
pop and catch arent inside the try function
Ah, I missed that 🙂
Yes, I'm using the same repo. I also use Paredit, could it be that paredit changed the content of the koan?
Ah got it. it's because of parinfer. Thank you!
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
Lots of people there use vim + fireplace
ahh, thanks
np
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?
is i possible to add up number in range and not using reduce
?
You could use apply
.
You can use apply: (apply + (range 10))
oke, I have to see how that can work in updating a atom
thanks for showing me this
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
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
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.
I use !
for mutating / impure stuff
e.g. medley is a small library with a single .cljc file published as a JAR on Clojars: https://clojars.org/medley
or is this simeple swap! atom (apply + (range 10))
?
okay okay got it, thanks! 🙌
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)
but now atomSum is 0 instead of the right answer.
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)))
that means that sum
returned a delay, not a number
swap! needs a function, a number isn't a function
swap! takes a function, apply is not returning a function
perhaps you want (swap! atom + (apply ...))
that does the job
(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)
the only thing I got is that part1 and part2 are not used
right, the only thing they do is make sure you don't deref the atom at the end before the futures are done executing
so it s not a problem that I have to solve ?
this code is good clojure code ?
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
oke
im was trying to solve this one
; 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?
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)
@rakyi I am not aware of that rule. Thx for the fn.
yeah - if you create both futures, then deref, it's faster (if you have multiple CPUs), if not it's slightly slower
(i misread sorry)
yep
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)))
I have a 4 core machine so cores enough
so this is better ?
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))
but much faster then this one :
(time (sum3 0 1e7))
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
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 😁
I use now vs code with the calva plugin
ok, the best experience is to start a repl, connect to it with vs-code, launch "evaluate current form"
start with inner expressions
like (/ 1e7 2), then (range ...) and so on
thanks for the hints
=> (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 😀
Hello Clojurians!
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)
welcome!
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
brb!
@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.
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)
Hey @seancorfield, nice to meet you! I will definitely let you know once I set up my personal email so you can deactivate this one
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?
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
Actually I'm gonna use my work email for now haha.
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.
No problem. Feel free to DM me any time if you need activation/deactivation on any of your email accounts here on Clojurians!
Yea thanks a lot! Looking forward to chatting with you more soon!
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
oof
to start off with that code should throw an exception and refuse to compile
the use of >!
in
(fn [response] (>! rep-chan response))
is not validso 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
next, the result of an expression like (go ...)
is always going to be a channel
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
ah, cljs.core*
missed that
that maybe why the compiler didn't throw an error about that invalid use of >!
, the cljs side of core.async needs some love
you must mean you are using cljs-http, not clj-http?
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
no I meant the one you linked to, back to cljs-http lol
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