This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-01
Channels
- # announcements (54)
- # asami (3)
- # aws (5)
- # babashka (8)
- # beginners (64)
- # biff (27)
- # calva (11)
- # cider (41)
- # clj-otel (7)
- # cljdoc (72)
- # clojars (20)
- # clojure (159)
- # clojure-austin (3)
- # clojure-europe (143)
- # clojure-italy (1)
- # clojure-nl (5)
- # clojure-norway (3)
- # clojure-uk (3)
- # clojurescript (19)
- # community-development (1)
- # core-typed (5)
- # cursive (3)
- # datalevin (1)
- # datomic (8)
- # emacs (13)
- # fulcro (4)
- # google-cloud (4)
- # honeysql (25)
- # java (1)
- # jobs (1)
- # lambdaisland (3)
- # lsp (121)
- # off-topic (52)
- # other-languages (1)
- # re-frame (3)
- # releases (2)
- # remote-jobs (1)
- # shadow-cljs (36)
- # sql (4)
- # xtdb (36)
Hello! I’m trying to figure out how to have a collection of vectors where the second element in each vector is the sum of the previous vector’s second element and a constant; like below - but I’m not sure how to approach it. Is it a bad idea to use something like dotimes if I have no side effects?
[10 5]
[10 10]
[10 15]
...
[10 30]
Yeah, for a lazy sequence... That would be better...
user=> (take 5 (iterate (fn [[x y]] [x (+ 5 y)]) [10 0]))
([10 0] [10 5] [10 10] [10 15] [10 20])
(deleted my bad suggestions due to misreading the Q!)
I would like to guard against data model changes in a big full-stack project. My feeling is that going full-blown spec
and test
is going to be a pain to maintain until the data model settles. Currently, I'm thinking of using a combination of hyperfiddle/rcf
(which would get turned into proper tests later on) and assertions (`:pre` or truss
, to be elided in production). Questions:
• Does this sound like a sound approach?
• I've seen that assertions can be elided in ClojureScript. Is there a way to easily switch them off in Clojure? (Both for production but also testing.) I'm using deps.edn
.
Any pointers welcome.
I think assertions can have a lot of value in production - I would use them wisely and keep them always on.
I got a question about the ->>
macro, in the following example, the req
is passed as the last parameter to the str
function, but I thought that was the goal of the ->>
macro?
(defn request-example [req]
{:status 200
:headers {"Content-Type" "text/html"}
:body (->>
(pp/pprint req)
(str "Request Object: " req))})
The last line there will actually become
(str "Request Object: " req foo)
Where foo
is the result of (pp/print req)
(which I imagine will be nil)Ah, I get it now. Have been mocking some calls around. The use of the ->>
macro isn't really required IMO as the result is indeed nil
and won't affect the str
call. Could this have been a simple do
function?
If you just want to do both lines, maybe you want do
instead ?
:body (do
(pp/print req)
(str "Request Object: " req))
?Yeah, that's also what I'm thinking. Kind of reinforces my belief that there is a lot of bad content on medium :face_with_hand_over_mouth:
I have a DDG addon for Firefox that lets you blocks domains from search results. One of the domains I block is http://medium.com, found its mostly crap.
Hello! I have a question with -> macro. How to append key value pair based on if condition. Below is the code snippet I am trying
(def page-data {:title "demo" :type "record" :body "body data" :abc "first" :metadata {:properties {:test-state "test" }}})
(let [new-payload (->
page-data
(select-keys [:title :type :body :metadata])
(assoc :version "v1")
(if (contains? (get-in page-data [:metadata :properties]) :editor)
(assoc [:metadata :properties :editor] :key "editor" :value "v1" )))]
(println new-payload)
)
But it is returning 'false'. Instead I would like to get response such as
{:title "demo" :type "record" :body :version "v1" "body data" :abc "first" :metadata {:properties {:test-state "test" :editor {:key "editor", :value "v1"} }}}
Your help greatly appreciated!As @U050ECB92 mentioned, macroexpand is nice for getting an idea of what’s happening.
Depending on your preference you might also want to look into using cond->
, though you’ll be adding some truthy indicator to every step that should always be running.
(let [new-payload (cond-> page-data
:always (select-keys [:title :type :body :metadata])
:always (assoc :version "v1")
(contains? (get-in page-data [:metadata :properties]) :editor)
(update-in [:metadata :properties :editor]
merge {:key "editor"
:value "v1"}))]
(println new-payload))
I switched to update-in
for the example since your snippet was using assoc
with a path which will actually turn into a key 😊
(assoc nil [:my :path] :value :another :value)
; => {[:my :path] :value, :another :value}
Awesome Thanks @UDB2Q0W13 It works for me.
No probs! Did you try macroexpanding yet? Illustrating what happens by switching out ->
with as->
:
(as-> page-data x
(select-keys x [:title :type :body :metadata])
(assoc x :version "v1")
(if x
(contains? (get-in page-data [:metadata :properties]) :editor)
(assoc [:metadata :properties :editor] :key "editor" :value "v1")))
Since page-data (`x`) is always true, the return value becomes the result from contains?
😊
If you don’t want to insert the value as the first argument you need to create an anonymous function like so:
(-> 1
dec
(#(if (zero? %) "Zero!" "Not zero")))
or in other words:
(as-> 1 x
(dec x)
(#(if (zero? %) "Zero!" "Not zero") x))
The code gets pretty ugly at this point so maybe define a function outside the threadwithout giving you the direct answer, one thing I recommend to run macroexpand
in your REPL:
(macroexpand '(-> a b c))
You'll need to quote the form that you're macroexpanding, but this will give you an intuition for why you're getting an unexpected response
(macroexpand '(-> a (if condition then else)))
Doing any IO in a transducer, like an HTTP request to get more data, is a bad idea?
Hmm, that's the impression I got from the first point here https://clojurians.slack.com/archives/C03S1KBA2/p1629991519027200?thread_ts=1629924688.380100&cid=C03S1KBA2
the actual reducing function argument to transduce
/`reduce` is often a side-effect. Maybe don't also do IO in the transducer (Remember transducers don't process data, they transform a reducing process that actually does the data processing)

I have a large data set which I need to transform in some ways (map, group-by), and then send an HTTP request to add some more data to it, before saving it in my own DB. The last part I was planning on doing in the reducing function. Is it okay to do the rest inside the xform part of the transducer, or do I need to separate this out in other ways?
So the side-effect (writing to DB) is isolated to the reducing function. This sounds like the right way to do that. I'm just not clear if I can make network requests and incorporate the returned data inside the transducer transformation, or if that should be done in the input to the transducer using map
or something.
What is the difference between https://clojuredocs.org/clojure.core/hash-set and https://clojuredocs.org/clojure.core/set?
user=> (hash-set 1 2 3)
#{1 3 2}
user=> (set [1 2 3])
#{1 3 2}
one takes values, one takes a coll
Use for wrapped in a recursive function to process tree shaped data (fn f [xs] (for [x xs i (f x)] i))
ifn? is true for all invokable things (fns, multimethods, keywords, collections, vars, ...) but fn? only returns true for fns. Prefer ifn?
You can give otherwise anonymous functions a name to refer to itself by, which is useful for recursion, but the name will also show up in stacktraces so is useful when debugging (fn thisisthename [anarg] anarg)
str is the identity function on strings, and is type hinted to return a String. You can use str instead of adding a String type hint to remove reflection.
Use update-in instead of assoc-in, you can always turn update-in into assoc-in using constantly
identity is the identity transducer, pass it anywhere you would a transducer to get the bare step function behavior
clojure.set/index can be used to build more complex key/value lookup structures like a database index
Sometimes(usually for debugging) you just want to stick a function literal in the middle of a -> or ->>, this won't work like (-> ... #(f 1 % 2) ...)
but will work like (-> ... (#(f 1 % 2)) ...)
Loop/recur cannot be used to loop across a try/catch, trampoline is useful for retry loops on exception
You can use (sort-by - ...)
as a handy reverse sort in some cases, but not all, see https://clojure.org/guides/comparators for a complete write up on clojure (and java) sorting
reducing for side effects is very nice, but as much as possible return some value from reducing, not just nil. Even just a count of reductions can be useful when debugging, testing, and logging.
clojure.core/deref works on anything that implements clojure.lang.IDeref or java.util.concurent.Future, as a consequence of how that is implemented if you try to deref something that is not derefable, you get an error about casting to Future failing.
tree-seq is for harvesting trees. it enumerates all the parts of the tree and you can keep want you want.

Calling str on a lot of clojure objects gives you a nice readable thing, but not on all clojure objects. Use pr-str instead
proxy is really weird. In 10+ years I've never used update-proxy. And proxy-super is not thread safe(it mutates the proxy object).
Is this an okay place to ask newbie hiccup questions? When I search for css & html help, I don't always know how to translate that to hiccup. For example, making an image bigger, or reducing padding somewhere, or centering text. I also get confused between what to edit: The hiccup in my cljs file, the css files, or my base.html
FYI: There are a couple of webapps that translate html-to-hiccup if you have some HTML and want to just paste it in and see how it would look as hiccup syntax. e.g. http://html2hiccup.buttercloud.com/
@U01EFUL1A8M I think I'm using in-line styles... I'm following an example from ClojureBridge London. Here's a snippet where I have an image in the navigation bar that I'd like to make bigger (not sure if there's padding that's making it smaller):
(defn navigation-top
[]
;; Navigation bar (responsive)
[:nav {:class "navbar is-fixed-top is-white has-shadow py-3"
:role "navigation"
:aria-label "main navigation"}
[:div {:class "container"}
[:div {:class "navbar-brand"}
[:a {:class "navbar-item"
:href "/"}
[:img {:src "img/logo.png"}]]
[:span {:class "navbar-burger burger"
:data-target "navbarClojureBridge"}
;; Empty spans needed for navbar burger
[:span] [:span] [:span]]]
[:div {:id "navbarClojureBridge"
:class "navbar-menu"}
[:div {:class "navbar-end"}
[:a {:class "navbar-item"
:href "/contact"
:style {:font-weight "bold"}} "Contact"]]]]])
@U05476190 Thanks! That's a great resource. I think now I'll feel a lot more comfortable googling html questions nkowing that I can translate them into hiccup
I think with the navbar the problem is that there is padding around the image, but I don't know how to get rid of it. I'm using bulma, so would I have to go digging through the bulma file?
> not sure if there's padding that's making it smaller Forget about html vs hiccup for a minute; you really want to get more comfortable with Chrome and/or Firefox Developer Tools. That will help you answer those kinds of questions, quickly test alternatives, and find the source of what's causing the root issue (e.g. some bulma class, some padding, etc). IMO, that is time well spent and will save you a lot of grief in the long run. ;)
Thanks!! I appreciate you pointing me in a productive direction
Another question: For example, I want text within a div to be centered vertically. I did a google search and found
.center {
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
As an example. How would I add a css style margin: auto
with hiccup?I'd prefer to stick to the hiccup files as much as I can instead of trying to change the css & html directly (Although I'd love to hear what best practices are?)
[:div {:style "margin: auto"} "Center Me"]
But you probably want to just do:
[:div {:class "center"} "Center Me"]
And then define the .center
class in a CSS fileCool thanks!!
If you are looking for example projects, my landing page is written with ClojureScript, reagent and http://Bulma.io (actually it's mostly bluma) https://github.com/practicalli/practicalli.github.io