This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-03-11
Channels
- # announcements (15)
- # aws (11)
- # babashka (13)
- # babashka-sci-dev (2)
- # beginners (63)
- # calva (20)
- # cider (9)
- # clj-kondo (27)
- # clojars (3)
- # clojure (34)
- # clojure-art (4)
- # clojure-europe (21)
- # clojure-filipino (1)
- # clojure-indonesia (1)
- # clojure-my (1)
- # clojure-nl (11)
- # clojure-norway (10)
- # clojure-sg (1)
- # clojure-spec (4)
- # clojure-uk (4)
- # clojurescript (5)
- # cursive (8)
- # deps-new (2)
- # events (1)
- # exercism (2)
- # fulcro (44)
- # graphql (6)
- # gratitude (1)
- # introduce-yourself (1)
- # jobs (3)
- # leiningen (5)
- # lsp (26)
- # membrane (18)
- # missionary (9)
- # off-topic (1)
- # pedestal (4)
- # portal (1)
- # quil (24)
- # re-frame (17)
- # reagent (5)
- # remote-jobs (2)
- # reveal (3)
- # spacemacs (4)
- # tools-build (1)
- # tools-deps (12)
Hi, I’m interested in learning clojure. The book Clojure for the Brave and True keeps coming up as a good source. If not mistaken this book was released about 7 years ago. I don’t know how much clojure has changed since then. Is the book still relevant or is it outdated?
you didn't ask but if you already know how to program then Getting Clojure is an amazing book for learning Clojure
There are lots of great resources for learning Clojure https://clojure.org/community/resources
and also @U05254DQM puts out this very excellent resource https://practical.li
it is very rare for existing Clojure language features to change, but some things have been added since then
(defmethod ig/init-key :adapter/jetty [_ opts]
(let [handler (atom (delay (:handler opts)))
options (-> opts (dissoc :handler) (assoc :join? false))]
{:handler handler
:server (jetty/run-jetty (fn [req] (@@handler req)) options)}))
what's mean "@@handler" , is it the first deref atom and after deref delay?Dereferences the atom
, which contains a delay
that also needs to be deferenced.
Yep. This section here, @U025AG2H55F https://github.com/weavejester/integrant#suspending-and-resuming
hi team I am exploring memoize function and when I run below code in IDE
(defn myfunc[a] (println "doing some work") (+ a 10))
(def myfunc-memo (memoize myfunc))
(def a 5)
(println (myfunc-memo a))
I expect it should return 15 only! why it returning doing some work
? I thought since I am running in IDE all the functions reload again! ( so it runs well in repl) So how can we make use memoize in production code
@popeyepwr if you run the whole code block every time then you keep redefining all the vars (functions) so my-func-memo
is a fresh thing everytime you run it.
Try to only load it once and then just evaluate (my-func-memo a)
a few times and see if it makes a difference.
@U06BE1L6T Thanks for your response! How can we make a single function separated ?
I have a function where I am calling from webservice,, So separating memoize function would be difficult in my case
@popeyepwr
I think there's some confusion here.
I was talking about the case when you are running the REPL and working on the application.
To see how it works, you can do as I suggested, that is evaluate the whole code block only once and then try to call (my-func-memo a
) , perhaps in the REPL, a few times.
I'm not sure what you mean by "separating memoize function would be difficult in my case" but you definitely don't need to move it to another namespace.
You can simply keep it as it is now
I think your trouble might be that you have only learned how to evaluate the whole buffer/file/namespace and the individual forms (like defn
)
@U06BE1L6T sorry for the late response , Yeh I understood how it behaves in repl, But how about production code where it calls the function again and again on refresh
Ah, I see. Sure, that's just calling the function. So the first time it will do the actual calculation, after that it will use the cached (memoized) value.
@popeyepwr — what happens when you evaluate your buffer in your IDE, the evaluate the last expression only in the REPL?
@popeyepwr — did you solve your issue?
I have a function inside a function, How to stop calling second function during recursion ?
Direct answer: You can create an exception object and analyze its stacktrace to see if there are multiple calls to some function. But i would not advise you to do that. Change the function instead
To clarify: is the second function defined inside the lexical scope of the first and subsequently called by the first? Or is it just called?
but I do not remember which is that function, like once promise object is already derefered, thenit would not call that function again, I lost that doc
I’m not sure if I understand the intent, but I can think of three ways to avoid evaluating the second function without things becoming too “magical”: • The arguments passed into the first function somehow affects if the second should run, so for example if you pass in a counter during recursion then it only runs when the counter equals 1 (or just not at all). • If the goal is to run the function only once, then store the evaluated value in an atom and during recursion check if the atom has changed from whatever the default value is • Use a dynamic var to turn evaluation on or off depending on the context
(def ^:dynamic *skip-evaluation* false)
(defn second-worker []
(prn "I do things!"))
(defn first-worker [x]
(when-not *skip-evaluation*
(reset! worker-result (second-worker)))
(prn "Loop number " x)
(inc x))
(first-worker 0)
(binding [*skip-evaluation* true]
(loop [x 0]
(if (> x 5)
x
(recur (first-worker x)))))
In this example the second-worker
doesn’t run during the loop-recur@popeyepwr — can you share function definition where promise is created?
Thread necromancy! I just stumbled upon the delay
-function which might help you achieve what you’re expecting:
https://clojuredocs.org/clojure.core/delay
(you have to define the delay outside the function body and “deref” it to make sure it runs once)
Hey guys, what is the best way to refactor the following code?
(defn printer-error [string]
(str (count (filter #(> (int %) 109) (seq string))) "/" (count string)))
(printer-error "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbmmmmmmmmmmmmmmmmmmmxyz")
; Output: 3/56
I tried to convert to thread first, but the filter expect receive as the last argument and count expect the result from filter.
(defn printer-error [s]
(-> s
seq
(filter #(> (int %) 109))
count
(str "/" (count s))))
The second approach was using as threading, but the problem now becomes on the result of filter.
(defn printer-error [s]
(as-> s string
(seq string)
(filter #(> (int %) 109) string)
count
(str "/" (count string))))
This approach works but I believe could be better somehow.
(defn printer-error [s]
(let [total-invalid-chars (count (filter #(> (int %) 109) s))]
(str total-invalid-chars "/" (count s))))
(defn printer-error [s]
(-> (filter #(> (int %) 109) s)
count
(str "/" (count s))))
Your intuition was spot on. This is the best, by far:
(defn printer-error [s]
(let [total-invalid-chars (count (filter #(> (int %) 109) s))]
(str total-invalid-chars "/" (count s))))
When reading your code without context, I needed to understand your intention. The function is supposed to find invalid characters, then print how many are invalid in relation to the length of the string. This version represents exactly that, no magic.concur with @U031CHTGX1T
(Personally: I'd let-bind invalid-chars
rather than their count, then (str (count invalid-chars) "/" (count s))
)
My point was: Use let
instead of trying to thread it all together
@U031CHTGX1T it was a Kata from CodeWars, just to practice some Clojure: https://www.codewars.com/kata/56541980fa08ab47a0000040/train/clojure
@U01RL1YV4P7 your code work perfectly! I though I need to convert to a seq before send into filter function
@U050ECB92 Agree with the count outside would be better in that solution 😄
Dumb question but what would be the Clojure way for transforming a list of words into a list of sentences? E.g. [ “Hello.” “How” “are” “you?” “I” “am” “fine.” ] => [ “Hello.” “How are you?” “I am fine.“] I’m thinking it’ll involve a reduce
.
(->> (-> (clojure.string/join " " [ "Hello." "How" "are" "you?" "I" "am" "fine."])
(clojure.string/split #"(?<=\.)|(?<=\?)|(?<=\!)"))
(mapv clojure.string/trim))
=> ["Hello." "How are you?" "I am fine."]

(defn group-words [words]
(let [n (atom 0)]
(partition-by (fn [w]
(let [i @n]
(when (re-matches #".*[.?!]$" w)
(swap! n inc))
i))
words)))
(group-words ["Hello." "How" "are" "you?" "I" "am" "fine."])
; => (("Hello.") ("How" "are" "you?") ("I" "am" "fine."))
(->> words group-words (mapv (partial clojure.string/join " ")))
; => ["Hello." "How are you?" "I am fine."]

partition-by
and mapv
both look like good solutions. Thanks.
The first suggestion can be simplified by including space(s) after the lookbehind:
(-> (clojure.string/join " " test-text)
(clojure.string/split #"(?<=[.?!]) +"))
;; => ["Hello." "How are you?" "I am fine."]
Another pretty elegant solution involves spec:
(require '[clojure.spec.alpha :as s])
(defn stop? [w] (re-matches #".*[.?!]" w))
(s/def ::sentence (s/cat :words (s/* (complement stop?)) :stop stop?))
Then conform the input:
(s/conform (s/+ ::sentence) ["Hello." "How" "are" "you?" "I" "am" "fine."])
; => [{:stop "Hello."} {:words ["How" "are"], :stop "you?"} {:words ["I" "am"], :stop "fine."}]
Now it’s just a matter of running map
over the result to conj
:words
and :stop
and join:
(->> ["Hello." "How" "are" "you?" "I" "am" "fine."]
(s/conform (s/+ ::sentence))
(map (fn [{:keys [words stop] :or {words []}}]
(conj words stop)))
(map (partial str/join " ")))
; => ("Hello." "How are you?" "I am fine.")
Note that you can easily extend this and get input validation for free.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Hi! I am fighting configuration problems for getting monger connected to Amazon DocumentDB via TLS using a connection URI. The same URI works perfectly fine with some node.js programs. I am using the following template and pass in the parameters via format
...:require [monger.core :as mg]...
...
(def connection-uri-template "")
(def connection-uri (format connection-uri-template user-name password db-server database ssl_ca_certs tlsCAFile))
(let [uri connection-uri {:keys [conn]} (mg/connect-via-uri uri)]
(do
(println connection-uri)
(def result (enforcement-proxy-groups-simple conn))
(println result)
)
(mg/disconnect conn))
I am getting a java.net.SocketTimeoutException: Read timed out.
I am missing something here. I wonder if someone could point me to a working configuration. Do I need a keystore file because we are running on the JVM? BTW, I am using Java 11.0.11, but I do not think that matters.The path to the tlsCAFile is encoded as I have it for the Node.js application.