Fork me on GitHub

Edit: I posted this in the wrong channel by mistake. I intended to post it in #growth. I made it worse by sharing it on that channel, and a discussion thread has already started there. So now I cannot delete it from here. My bad! Here’s a thought that’s been sloshing around in the back of my mind recently… At work, I use Python. When I get stuck with something, I tend to Google for help. Usually, the top 5 search results point me to an answer on Stack Overflow, which solves my problem. However, with Clojure, the best place to ask is here on Slack. And by searching on Slack, I observed that the same question has often been asked and answered several times (wasted effort). But it did not show up in Google because the answer is “hidden” in Slack or elsewhere. There is also a fair amount of duplication between Slack and Zulip. I wasn’t aware of Clojurians Slack when I started. I didn’t discover this community until I was ~6 months in. I couldn’t find all the excellent answers and help on Slack through Google, so I thought the Clojure community was just super small or silent until I stumbled into Slack. We invest much time providing help for beginners, but the content we create is not as discoverable and reusable as it could have been outside of Slack, Zulip, Clojure Q&A, and ClojureVerse. Therefore, we should encourage people to ask questions on Stack Overflow instead of Slack, then answer them there. The effort required would be more or less the same, but the content reusability (and time saved) would be more significant. Also, Clojure does not have much activity compared to other programming languages on Stack Overflow. This is not necessarily a bad thing. It could mean that Clojure is easier to use or that Clojurians are more experienced and tend to ask fewer questions. But we can see many questions coming in via Slack, etc.

👍 1

As far as I know, SO doesn’t mind if you add both the Q and A for documentation purposes. It’s I think even a primary use case as opposed to being a historical record of social interaction.

💡 1

That’s not a bad idea, @U01EFUL1A8M! It’s a good suggestion. However, it would involve more “clerical work” than just asking and answering the questions there directly.


To me it sounds much better to more often remember to do what @U01EFUL1A8M suggests, than to encourage beginners to ask somewhere else than where they want to ask the question. A beginner will get much, much better help here on Slack than they get on a forum like SO. I think it is a general trend that SO does not have as much content for newer languages as for older ones that were about back when SO was more often the better option. It doesn't sound to me like you, @U01PE7630AC, were encouraged enough to go ask here, since it took you so long. 😃


Also, I think, is a good place to build up a discoverable body of Clojure Q&A:s.

👍 3

I just didn’t know about the existence of Clojurians Slack 🙂 Perhaps I was living under a rock… If I recall correctly, I stumbled upon a link to Slack on the Clojure website and created because the link was broken at the time. As soon as I got in, I thought to myself: “Aha! So this is where all the stuff is happening.”


By the way… The first community site I discovered was the ClojureVerse. I had come straight from the incredibly vibrant Elixir community (which also uses Discourse for their platform) and found ClojureVerse to be inactive in comparison. The Clojure community turned out to be equally vibrant (perhaps even more so!), but most of the action was “hidden” inside Slack 😅


I don't know guys... I agree that the Clojurians Slack is an incredible and fairly unique resource for Clojure help. But SO has become a de facto standard for answers to questions about how to use a language. The advantages there are searchability, the votes (seeing community support all answers and their position relative to others), and de-duplication. I think that second advantage is particularly important because it helps everyone understand how to do things idiomatically.


It's tough enough learning all the conventions of a new language, but when most devs are coming from languages in a completely different paradigm (OOP) its so difficult to have any intuition about what answers are better than others.


Maybe instead of asking beginners to go to SO for answers, we can answer them here and then transfer those Q&As to SO later for reference?


(defn wrap-args
  "Wrap `f`, in a function that applies `fns` to each arg,
  then calls `f`"
  [f & arg-transforms]
  (fn [& args] (apply f (for [op arg-transforms arg args] (op arg)))))

((wrap-args + inc) 10)
=> 11
does this function already exist in some simpler form? Or should I just use fn


I start seeing an issue with this: it is an elaboration on multi arity and multi arity is complex because of the list order idea

Alexis Schad12:05:29

That's a strange pattern yes. Your example can be write as ((comp + inc) 10) but if you have another more complex example that uses the for?

quan xing08:05:04

I use clojure's map, not get my hope result :

(defn map-userui-lst-auditform
  " (map-userui-lst-auditform [197,196])"
  [conn userid-vec & [version]]
  (let [lst (sql/select-userui-in-userid conn userid-vec)]
    (map (fn [a-userui]
           (tranform-userui-auditform a-userui version)) lst)))

(map-userui-lst-auditform (db/ds) [196 197] "8de12617b8a34b559c1b4cd5dab4c1a71")
({:userId 196, :name "Jhon", :data []}
 {:userId 197, :name "4111111", :data []})

when I use "8de12617b8a34b559c1b4cd5dab4c1a71" replace version var. the result is like down.
(defn map-userui-lst-auditform
  " (map-userui-lst-auditform [197,196])"
  [conn userid-vec & [version]]
  (let [lst (sql/select-userui-in-userid conn userid-vec)]
    (map (fn [a-userui]
           (tranform-userui-auditform a-userui "8de12617b8a34b559c1b4cd5dab4c1a71")) lst)))
;; when I exeucte down code. the result is right
(def lst (sql/select-userui-in-userid (db/ds) [197,196]))
(map (fn [a-userui]
       (tranform-userui-auditform a-userui "8de12617b8a34b559c1b4cd5dab4c1a7")) lst)
==> ({:userId 196, :name "Jhon", :data []}
                                                                       {:userId 197,
                                                                        :name "4111111",
                                                                        [{"msg" "abc",
                                                                          "label" "abc",
                                                                          "newValue" "",
                                                                          "applyUserName" "a",
                                                                          "value" "abc",
                                                                          "applyUserId" "1",
                                                                          "version" "8de12617b8a34b559c1b4cd5dab4c1a7",
                                                                          "date" "2022-05-13 09:45:46"}
                                                                         {"msg" "",
                                                                          "label" "",
                                                                          "newValue" "",
                                                                          "applyUserName" "a",
                                                                          "value" 197,
                                                                          "applyUserId" "1",
                                                                          "version" "8de12617b8a34b559c1b4cd5dab4c1a7",
                                                                          "date" "2022-05-13 09:45:46"}]}
why I use 'version' variable in map-userui-lst-auditform not get my result.

Alexis Schad10:05:05

It should work. Are you sure you don't have any side effect that could alter the results? Like in your example, the first non-working version uses [196 197] for userid-vec and the others maybe [197 196] (don't know for the second one)

Alexis Schad10:05:43

And not directly related but is there any reason to do a & [version] instead of version directly? (Maybe it's just for debugging a later & args version)

quan xing00:05:02

Yes. It work. I restart clojure. It's ok. Thanks


Hi everyone, I defined my entities using defrecord and also use spec for data validate/generation. The problem is the generated values using the spec/gen are simple maps rather than records. What's the easiest way to modify those generators to transform to records without having to completely redefine the generators from scratch using test.check.generators? Thanks a lot

Alex Miller (Clojure team)12:05:58

I would assume it's using fmap to apply the record ->map constructor


Thanks, Alex, Yeah, I did that by passing the transformed generator to spec/gen But I assume that is not doable when defining the spec, which is ideally where one would want to specify this, or am I missing something - or otherwise, we have to do this everywhere we wish to generate from the spec?

(spec/gen ::parent-entity
     #(gen/fmap (fn [x]
        (rlc-core/map->Order-Book x))
          (spec/gen ::i-rlc/event))

Alex Miller (Clojure team)13:05:22

you can use s/spec to wrap a spec with a custom generator

Mark Wardle12:05:43

Hi I simply use fmap to turn the map into a record, and make that generator the main way my client code generates those entities - e.g. see - e.g. I use (gen/generate (rf2/gen-concept))

Mark Wardle12:05:55

I often have the need to generate synthetic data with one or two properties defined, so I have a varargs generator that can override generated properties with anything explicitly stated.


Thanks, @U013CFKNP2R got it but I had to define a second spec who wraps and uses the initial spec.

(spec/def ::__entity__ ,,,)
(spec/def ::entity 
  (spec/spec ::__entity__ 
             :gen (gen/fmap map->Record 
                            (spec/gen ::__entity__))))
Since I wanted the spec names be the ones that gets passed around.

👍 1

Hi, I created compojure + buddy project. Very basic API and i found myself doing

(auth/check-auth! request)
in all handlers (which basically uses buddy.auth/authenticated?) which feels like it should be middleware or that should be done automatically I am using buddy JWT (stateless) authentication (no authorization at the moment) Are there any examples of this online? I saw few with compojure.api but i wanna stick with plain compojure at the moment


this should be done in middleware, for sure

🙌 1

I think i figure it out.

(defn wrap-check-auth! [handler]
  (fn [request]
    (prn "requ: " request)
    (when-not (auth/authenticated? request)
      (auth/throw-unauthorized {:message "Missing or expired token"}))))
I just unwrapped the routes that don't need to be authed example /login


Thank you for your time!


Is it possible to create a function/macro that adds a key and value to a map

{:name "Joe"
 :age 24
  (magic "Joe")}
and get
{:name "Joe"
 :age 24
 :address "123 Sesame St"
 :spouse {:name "Jane"
          :age 21}}
assoc-in, merge and others are nice and work. I'm just curious and don't think i can offer an explanation beyond hashmaps expect an even number of elements.

Alex Miller (Clojure team)14:05:34

no, you can't do that. this would need to happen in the reader, which is before macros have an opportunity to do anything

👍 1

@U064X3EF3 exact answer i was looking for! Thanks

Alexis Schad14:05:51

and (indeed) there's no user-defined reader macros in Clojure


How does one pretty print clojure edn but in the browser using javascript (and not clojurescript) ? Is it even possible? and follow up question -> is it possible to send edn from javascript?


I would say the better answer would be to use transit when going between languages if you want to maintain the clojure data model

👍 1

idk what edn libs exist for js


though im sure there is one out there


edn is more readable that's why i would prefer it over transit but i noticed that transit it muuch faster. I will see what decision i make thanks a lot