This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-06
Channels
- # announcements (2)
- # babashka (22)
- # beginners (93)
- # calva (12)
- # cider (65)
- # clj-kondo (15)
- # cljdoc (5)
- # cljs-dev (4)
- # cljsrn (4)
- # clojure (65)
- # clojure-europe (2)
- # clojure-italy (1)
- # clojure-nl (1)
- # clojure-norway (1)
- # clojure-spec (40)
- # clojure-uk (7)
- # clojurescript (12)
- # conjure (1)
- # cursive (2)
- # data-science (13)
- # datomic (1)
- # dirac (12)
- # emacs (3)
- # figwheel-main (19)
- # ghostwheel (5)
- # helix (6)
- # kaocha (1)
- # leiningen (6)
- # news-and-articles (2)
- # off-topic (17)
- # pathom (5)
- # re-frame (59)
- # reitit (17)
- # restql (1)
- # shadow-cljs (31)
- # spacemacs (5)
- # spire (3)
- # sql (35)
I am trying to understand the use of comp
in transducers. It would seem that normally comp applies functions right-to-left but left-to-right when used as a transducers. Is this correct? My brain hurts:exploding_head:.
It still composes functions right to left, but in the case of tansducers, that's the order they need to be composed in for the transducers to apply the transforms left to right
Are you saying the functions are composed right to left, but the transducer flips it around?
Ah. I see. is there a reason I would want to use (sequence xf coll)
over (map xf coll)
?
It just happens that the way transducers work, when you do: (a (b (c xf coll))) For each element in coll, a will process it first, then b, then c, then xf
Thanks @U0K064KQV! Did you see the question about (sequence xf coll)
and (map xf coll)
?
But ya, it just means when you use comp with transducer, the logical order of the data transformation is now left to right, but the actual functions are still composed the way comp does.
Hum... I'm trying to remember 😝 I think I wrote something explaining it let me find it
Ok, did not find it. Even I always forget because it's a bit confusing the difference between transducer, lazy sequence, and sequence xf
I'm a bit fuzzy, but the difference is mostly that (sequence xf) will not create as many intermediate objects, so it should be a little faster than lazy-seq (which is what default map would do)
Ya it's complicated. Basically (map mapping-fn coll) is using lazy seq, no transducer involved here
While (sequence xf) wraps a transducer inside a lazy-seq. This then means you can process the transducer lazily. Because normally transducers are eager
I'm off to bed. Transducers take a long time to understand how they work. But to get the hang of using them is pretty quick. Good luck
What helped me to understand the inverse ordering with comp and transducers was to carefully study the source code
Ya it's complicated. Basically (map mapping-fn coll) is using lazy seq, no transducer involved here
I'm trying to write an endpoint test for my api rest, I'm using component on it. But basically I thought I had to do a (component / start (system))
before (deftest) but doesn't work. Someone have a link to help?
You probably want to define a fixture that starts your component system, runs the test, then stops the system afterwards. See https://clojure.github.io/clojure/clojure.test-api.html#clojure.test/use-fixtures
Here’s a link that explains it better: https://stackoverflow.com/questions/16350504/clojure-how-to-use-fixtures-in-testing
hola amigos im new to java, clojure and ring. so i'm trying to extract an information but i haven't found any resources on google
{:file {:filename "fdf.txt", :content-type "text/plain", :tempfile #object[java.io.File 0x2fc9a402 "/tmp/ring-multipart-11354728889402997926.tmp"], :size 55}}
this is map of my request, i don't understand this part #object[java.io.File 0x2fc9a402 "/tmp/ring-multipart-11354728889402997926.tmp"]
. my only understanding is that this is a java Object ?
i want to extract the string "/tmp/ring-multipart-11354728889402997926.tmp"
out of that, any idea how to do that?What you have there is a https://docs.oracle.com/javase/7/docs/api/java/io/File.html instance and I'm guessing you want to extract it's absolute path as a string?
If so, then you'll want something like:
(.getPath (:tempfile my-map))
You'll probably also need to add an import for http://java.io.File to your ns form.
Hi, i need to import java.math class to use log function but i cannot require it inside leinengen project do i need to add it into project.clj?
If you did need it, you would use :import, not :require
ok, i can use function from java math like this (java.lang.Math/log 3) but how can i get the namespace name for use in import? This is propably the problem 🙂 and thanks for help!
There are more info here: https://clojuredocs.org/clojure.core/import
thanks! i searched books and stuff like this but clojuredocs is best 😉 just quick question i used io like this
(ns programming-ml.fourth
(:require
[ :as io])
is it worse? and how should i know that the path is actualy http://clojure.java.io ?
looks fine to me. I think problem of "discoverability" is the same as other languages, you can improve a little by using code completions
frameworks in your editor of choice. But also, would encorage an overview of https://clojure.github.io/clojure/clojure.core-api.html at least the high-level namespaces available at the core. Clojuredocs and searching in general helps a lot.
thank you
I'm trying to make a command line application with some animations in the terminal. I've found out how to replace one line (using carriage return), but is there a way to replace several lines? For example, what I'd like is something like this:
|––| |--|
|--| --> |xx|
|--| |--|
i’ve used lanterna for a similar use case, https://github.com/mabe02/lanterna
And if you’re familiar with ANSI escape codes and want something lightweight, https://github.com/xsc/jansi-clj is quite good too.
how does clojure.walk/walk avoid a stackoverflow exception, from the looks of it it doesn't do anything fancy with recur and it's basically just calling itself over and over isn't it?
or is it down to the fact that the function being called oscillates between post/prewalk and walk
It doesn’t avoid it, it can overflow
Oh interesting, I realise now that in the specific case of a seq it doesn't do much recursion so testing on (range)
was pointless, mb! Thanks for the information 🙂
I'm trying understand how I write test to endpoint to my API. I have this test
but when I run lein test
my server always stay in running. May someone can help? This is api is for me understanding how component works and how write testing using components.
fixtures was going to be my suggestion, what did you have, something like:
(defn with-system
[f]
(let [current-sys (component/start (start-test))]
(f)
(component/stop current-sys)))
(use-fixtures :each with-system)
I think the testing bit is missing your handler
(ns cracking.budget-test
(:require [budget-calculator-api.components.routers :as routes]
[clojure.test :refer [deftest testing is use-fixtures]]
[ring.mock.request :as mock]))
;;; add your fixture defined above. looks fine to me.
(deftest testing-endpoint
(testing "GET"
(let [resp (routes/router (mock/request :get "/"))]
(is (= (:status resp) 200)))))
Thank you! Im my run-jetty I create a warp-storage to inject in my route I don't know if this is good clojure practice. But I would like to know if I can easily replace the memory storage with a mock in my router?
(defn wrap-storage [f storage]
(fn [req]
(f (assoc req :storage storage))))
(defn create-server [port storage]
(run-jetty (-> #'budget-calculator-api.components.routers/router
(wrap-storage storage)
(wrap-json-body {:keywords? true})
(wrap-json-response)) {:port port :storage storage}))
Are you creating your storage
instance as part of your system start? If so, you could change your system map to point to the mock storage before starting the system in your fixture.
I did this, but if I use my system (start-test) it keeps running and doesn't call the test
(defn with-system
[f]
(let [current-sys (component/start (start-test))]
(f)
(component/stop current-sys)))
(use-fixtures :each with-system)
(deftest tt
(testing "GET"
(let [resp (routes/router (mock/request :get "/"))]
(is (= (:status resp) 200)))))
(start-test) return my system map, then I use (component/start (start-test)) tu run my system
Sorry, by “not returning” I mean you call it but it hangs, never returning a value.
Many Clojure devs use a little macro to debug things like this…
(defmacro dbg [x] `(let [x# ~x] (println '~x x#) x#))
Then you can write (dbg (component/start (dbg (start-test))))
to see what each function is returning.
@UL618PRQ9 your run-jetty
function is holding the process. You need to pass :join? false
in the same map you configured the port. From the run-jetty
documentation you can find:
:join? - blocks the thread until server ends (defaults to true)
I have a scheduled job in it that puts data on a channel, but it just closes instantly before processing any data. (while true)
works but my pc doent like it. Is there a more lightweight way to do it?
yeah, while true is obviously not going to throttle in any useful way in-and-of-itself and will happily consume a CPU core. one way to go about this would be to have a second channel you take (`<!!`) on, and when you're done with what's happening in your go
block, send a value (maybe an error), or just close that channel.
another way would be to use something like promesa, do very much the same thing, and deref the promise - and resolve that promise once you're done with your async work.
yet another way would be to just block synchronously - and that's the most simple option if you don't need multithreading. depending on what you're doing, async/multithreading can actually slow you down - or, at the very least, your async code will be dependent on your slowest execution path.
yet another way 😉 if you're using CLJS with Node - the Node event loop will block until all event handlers have been removed. so you could create some arbitrary event handler using once
and trigger that event when done.
I used a asynch channel with timeout but I swapped it out now with Thread/sleep
inside the loop. That will work for now. Thanks.
I usually have a promise
inside my (long-running) processes and just "wait" on it in -main
(via a deref).
https://github.com/seancorfield/usermanager-example/blob/master/src/usermanager/main.clj#L221-L229
Normally, that will just "wait forever" but if you start a REPL in the server, you can connect to it and deliver the promise to cause it to shutdown, or you could program some external action in your server that also delivered the promise to cause it to shutdown.