beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Lukas 2021-05-28T09:08:44.073Z

Hey, not sure if this is the right place to ask: I'm using pedestals response-for function:

(test/response-for (:io.pedestal.http/service-fn @lhrb.server/server)
                     :post "/q"
                     :headers {"Content-Type" "application/edn"}
                     :body "(+ 2 2)")
After the first eval, changes to the request body do not have any effect and I always get the first request returned. Could anyone help me resolve this Issue?

Lukas 2021-05-28T09:26:46.073600Z

Okay seems like it's not an issue with the response-for fn, since I observe the same behavior with curl

Lukas 2021-05-28T09:33:16.075400Z

Oh gosh my bad ... I had a var in the repl which I used instead of the argument passed by the function. ๐Ÿ™ˆ Sry

Timofey Sitnikov 2021-05-28T11:00:11.077600Z

Good morning, I am puzzled by the https://github.com/drewr/postal/blob/7606a66c10b66abd3476c6f4c828fb4b87d3792d/src/postal/core.clj#L29, which is the following:

(defn send-message
  ([{:keys [host] :as server}
    {:keys [from to bcc subject body] :or {to "" subject ""} :as msg}]
     (when-not (or (and from to)
                   (and from bcc))
       (throw (Exception. "message needs at least :from and :to or :from and :bcc")))
     (if host
       (smtp-send server msg)
       (sendmail-send msg)))
  ([msg]
     (send-message (meta msg) msg)))
In the function definition, after the function name there is is a function call, where are the function parameters?

NoahTheDuke 2021-05-28T11:15:23.077900Z

https://clojure.org/guides/destructuring

tvirolai 2021-05-28T11:55:16.079800Z

They're not actually function calls, although they're written similarly. The function has two arities (see https://clojure.org/guides/learn/functions#_multi_arity_functions) defined for it, so there are two distinct function bodies, one for arity of two (server, msg) and the latter for arity of one (msg).

1
Timofey Sitnikov 2021-05-28T12:09:03.081400Z

@tvirolai, thank you for clarifying, I did read about it, but for some reason it did not register as such.

bastilla 2021-05-28T13:21:33.083Z

Altering a data structure (map) multiple times (in a stateful way) with one line (without loop/recur) A simple question here regarding basic techniques. The case of 'altering stuff one single time' is page-3-stuff of any book, of course:

(let [cat-v [:data :content :objects]
	  dim-app-db (assoc-in app-db cat-v {})]
  ;; Process dim-app-db
Now I want to alter the target structure multiple times. My imperative mind set keeps producing this code:
(let [categories '([:data :content :objects]
     			   [:data :content :media :objects])
	  dim-app-db (let [func (fn [db categories]
				                (if (empty? categories)
				                  db
				                  (recur (assoc-in db (first categories) {})
				                         (rest categories))))]
				        (func app-db categories))]
  ;; Process dim-app-db
But this is quite some clutter. I was thinking of a more lispy/functional way of altering the target structure (app-db) multiple times. Stateful transducers came to my mind. I read about it, but couldn't pattern match it into my needs so far. Is there a one-liner that does the job more graciously?

NoahTheDuke 2021-05-28T13:23:40.083500Z

why do you want to avoid loop/recur? it does what you want

NoahTheDuke 2021-05-28T13:25:06.085Z

lemme see if i can rewrite what you have

NoahTheDuke 2021-05-28T13:25:43.085800Z

(let [categories '([:data :content :objects]
                   [:data :content :media :objects])
      dim-app-db (loop [db app-db categories categories]
                   (if (empty? categories)
                     db
                     (recur (assoc-in db (first categories) {})
                            (rest categories))))]
  ;; Process dim-app-db

๐Ÿ™Œ 1
bastilla 2021-05-28T13:26:32.086700Z

Hi @nbtheduke . I don't want to avoid it at all cost. It's fine with me. (I LOVE loop/recur, in fact). I was just wondering if I do total beginner's mistakes. Maybe there is a way shorter technique and I just don't know it. This is a standard case, and I write this code quite often. (And it's lenghy and requires a new fn all the time.)

bastilla 2021-05-28T13:28:08.087700Z

Ah, yeah, that's better code for sure. About the same lenght, and the approach has not changed. But certainly more elegant. Thanks!

NoahTheDuke 2021-05-28T13:29:03.088Z

thereโ€™s also reduce

NoahTheDuke 2021-05-28T13:29:12.088300Z

dim-app-db (reduce #(assoc-in %1 %2 {}) db categories) i think (havenโ€™t run that)

NoahTheDuke 2021-05-28T13:30:10.089600Z

first arg to the reducing function is the accumulator, second is the current value from the sequence, and the accumulator (which starts as the db) is returned at the end

๐Ÿ‘ 1
๐Ÿ™Œ 1
bastilla 2021-05-28T13:30:44.090200Z

Hrm... you sure this works? If so this is exactly what I was looking for. 1 millions thanks, man!!!

NoahTheDuke 2021-05-28T13:34:00.090800Z

https://clojuredocs.org/clojure.core/reduce

bastilla 2021-05-28T13:36:16.092800Z

Yeah, just reading this! ๐Ÿ™‚ I knew reduce but wasn't aware it's capable of such things also. Awesome. Only downside is, I have to change A LOT of code now, lol. No, seriously, thanks. I had a moment of epiphany.

๐Ÿ˜‚ 1
๐ŸŽ‰ 1
NoahTheDuke 2021-05-28T13:37:48.093200Z

so glad to help!

stagmoose 2021-05-28T15:14:22.096200Z

I expected (map (comp (map inc) vector) [1 2 3] [1 2 3]) will give me ((2 2) (3 3) (4 4)) But it give me (#object[c] #object[c] #object[c]) instead. Is there anyone know how to explain this or what keywords should I look for? Thanks !

dpsutton 2021-05-28T15:15:58.097Z

(map inc) is a transducer. If you switch to (partial map inc) you'll get your intended behavior

stagmoose 2021-05-28T15:18:04.097100Z

Thanks! I'll go search for related concepts. ๐Ÿป

Max 2021-05-28T15:36:07.098900Z

When youโ€™re doing simple conversions from one coll type to another, do you prefer to use set/`vec`/`list*` or (into #{}/[]/())? Or when would you prefer one or the other?

ghadi 2021-05-28T15:38:46.099400Z

converting to a concrete list/seq isn't usually necessary

ghadi 2021-05-28T15:39:34.100300Z

I use set/vec if it's a simple coercion, if there are more transformations I consider using (into [] transducer collection)

Max 2021-05-28T16:03:45.101400Z

Yeah for me this comes up most often when I need the specific properties of a particular collection, for example using a set to check membership or a vec to ensure end-appending with conj in a reduce or something

practicalli-john 2021-05-28T17:26:12.106Z

Can I use clojure sets as a key in a hash-map, using a value within that set key as a lookup to get the value associated with the key? For example, I have a set of pet types that are collectively called pets. If I call get on the hash-map with "Cat" as an argument, then I would like to get "Pet" as the result. Instead I get nil, so it seems I am missing something. (assume I have a long list of sets and associated group names I want to call them, which I'd like to use as a lookup)

(get {#{"Cat" "Dog" "Rabbit" "Hamster"} "Pet"} "Cat")

dpsutton 2021-05-28T17:28:19.107Z

no you cannot. and in general that wouldn't be well-defined (get {#{:a :b} :foo #{:a} :bar} :a) would have two valid choices for lookup

dpsutton 2021-05-28T17:30:14.108300Z

but if your domain has disjoint sets you could roll your own deftype that had the sets and then "unrolled" the sets into a regular map with each key in the set attached to the value for the set. and when you dissoc you drop all of the keys from that set

2021-05-28T18:00:40.108500Z

clojure.set/index

sova-soars-the-sora 2021-05-28T20:05:35.109500Z

I want to detect customer country by ip address and show a handful of nations one page and have a default for the others... any reasonable index of ip prefixes to countries one can use?

seancorfield 2021-05-28T20:29:38.110500Z

@sova Not really. IP address groups arenโ€™t all that geographic in nature and theyโ€™re very fragmented. Best option is to use a service like http://ipinfo.io

sova-soars-the-sora 2021-05-28T20:44:20.110700Z

Right on right on

sova-soars-the-sora 2021-05-28T22:20:00.112100Z

clj-http: status 404 {:status 404, :headers {"referrer-policy" "strict-origin-when-cross-origin", ... I'm not sure what's up, if I run this locally the client/post works fine, but from the live box it returns an error

sova-soars-the-sora 2021-05-28T22:20:31.112400Z

would this be my middleware preventing a clj-http.client/post ?

indy 2021-05-28T22:26:13.112500Z

Does doing a curl of the same request from the live box work?

sova-soars-the-sora 2021-05-28T22:27:25.112700Z

good question

sova-soars-the-sora 2021-05-28T22:27:54.112900Z

it does

sova-soars-the-sora 2021-05-28T22:29:33.113100Z

I switched to client/get and it works

sova-soars-the-sora 2021-05-28T22:29:35.113300Z

๐Ÿ˜„