Fork me on GitHub
#beginners
<
2022-11-02
>
Eugene Mosh10:11:54

Hello friends! ♥️ Form (take-nth 5 (range)) produce lazy sequence 0 5 10 15 20 25 ... Is there some kind of "reverse take-nth" which produce lazy sequence 1 2 3 4 6 7 8 9 11 12 13 14 16 17 ... Thanks!

tomd11:11:09

There's not, but you could make one using lazy-cat:

(defn drop-nth [n coll]
  (when-let [s (seq coll)]
    (lazy-cat (take (dec n) (rest s)) (drop-nth n (drop n s)))))

Eugene Mosh11:11:37

:hugging_face:

tomd11:11:40

Also keep-indexed may be a simpler approach anyway:

(defn drop-nth [n coll]
  (keep-indexed #(when (pos? (rem %1 n)) %2) coll))

Eugene Mosh11:11:27

:star-struck:

Dajana Herichova12:11:11

(defn drop-nth [nr] (concat (range nr) (drop (inc nr) (range)))) this is what I would do :)

tomd12:11:29

@U0404ASMSCT unfortunately that just drops n. @U03D1PUDM6W is asking how to drop every nth

Dajana Herichova12:11:01

oh, that‘s true, I read the question wrong :woman-facepalming::skin-tone-2:

🙂 1
Dajana Herichova13:11:46

But this may work (defn drop-every-nth [nr coll] (remove (set (range 0 (inc (count coll)) 5)) coll))

tomd13:11:40

(where 5 is replaced with nr) yes, it works, but it's less performant, especially for small nr and large coll:

user> (time (do (doall (drop-every-nth 2 (range 1e7))) nil))
"Elapsed time: 7732.980416 msecs"
nil
user> (time (do (doall (drop-nth 2 (range 1e7))) nil))
"Elapsed time: 4933.956869 msecs"
nil

👍 2
Ed17:11:15

I would think of it as partitioning and then dropping, maybe something like

(->> (range 30)
       (partition-all 5)
       (mapcat rest))
In my mind, an advantage of this approach (and the keep-indexed approach mentioned by @UE1N3HAJH) over the lazy-cat or concat version is that it converts very easily to a transducer form, which is useful if you need to refactor later
(into [] (comp (partition-all 5) (mapcat rest)) (range 30)) ;; => [1 2 3 4 6 7 8 9 11 12 13 14 16 17 18 19 21 22 23 24 26 27 28 29]

👍 1
Alastair Hole13:11:17

Hi all, apologies if this is done to death but I’m wondering what would be a recommended HTTP client? So far clj-http seems like a good option (keen to have retries built in)

Alastair Hole17:11:52

Thanks, does it have support for retries?

pppaul17:11:39

isn't that very easy to do via loop or something

pppaul17:11:09

if you want something much more sophisticated there are libs like https://github.com/xsc/claro

pppaul17:11:00

http-kit says it's based on clj-http, which has retries. so i'm guessing that kit probably has that too

Alastair Hole17:11:19

Where does it say that?

Alastair Hole17:11:28

I think clj-http just has retries as it’s based on the Apache HTTP client

Alastair Hole17:11:42

kit doesn’t seem to mention retries

pppaul17:11:35

you have to look in it's code to be sure. may also want to look at how clj-http does it, cus if it's just a line of code or something you may be putting too much value on that feature

Alastair Hole17:11:07

There doesn’t seem to be anything in the kit code for it I can see

walterl17:11:13

I like https://github.com/sunng87/diehard for retries (of any kind).

👀 1
pppaul17:11:12

that's a lot better, now you have the same retry interface for different things in your app

👍 1
Alastair Hole17:11:38

True, though HTTP requests will be the only thing in this case

Alastair Hole17:11:37

Are there any reasons in particular to go with kit over clj-http? Lack of dependencies in the former perhaps but that’s not much of a concern

Alastair Hole17:11:57

I certainly like the idea of retries out of the box without having to think about it

walterl17:11:12

I tend to go for clj-http, if only because clj-http-lite often doesn't have features that I want (like proxy support)

walterl17:11:24

Haven't used http-kit, though

pppaul17:11:20

http-kit has a focus on concurrent features, probably could be implemented with core.async or manifold without much effort

Jared Langson17:11:31

How can I make a function that takes a collection and a variable number of functions and maps every function to the collection? A sketch of the function:

(defn map-multiple-functions [coll & funcs]
 (->> coll
   (map func1)
   (map func2)
   ...
  (map func-n))

hiredman17:11:55

or even just comp

👍 1
hiredman17:11:10

(map (apply comp funs) coll)

❤️ 1
pppaul17:11:10

looks like comp from the code example

hiredman17:11:35

(reduce #(map %2 %) coll funs)

👍 1
Jared Langson18:11:16

Stylistically, is one solution more readable than the other?

hiredman18:11:01

(sequence (apply comp (reverse (map map funs))) coll)

hiredman18:11:47

the first comp example is going to be more efficient

Nathan Spears18:11:48

don't you need a reverse in there?

(map (apply comp (reverse funcs)) coll)

hiredman18:11:23

oh, maybe, could be I switched the reverse in the first comp and the sequence examples

hiredman18:11:56

user=> ((comp inc (partial * 2)) 0)
1
user=>

hiredman18:11:40

user=> (sequence (comp (map inc) (map (partial * 2))) [0])
(2)
user=>

Matthew Twomey20:11:42

Considering this:

(let [foo "bar" baz foo] baz)
;; => "bar"
I’d like to construct the let bindings outside of the let, is this possible if it’s self-referential? e.g.
(let bindings baz)
;; => "bar"

Alex Miller (Clojure team)20:11:42

let takes a literal vector - it's a special form that expects that as part of its syntax, so this is not possible regardless. but what are you really wanting to do?

pppaul20:11:41

you can do a nested let

Matthew Twomey20:11:47

Well - I have a set of configuration variables such as:

(def company_auth_params {
                           :dev {:code-challenge "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                                 :code_verifier "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                                 :client_id "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                                 :auth-header "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                                 :redirect_uri ""
                                 :login_uri ""
                                 :authorize_uri ""
                                 :token_uri ""}
                           })

Matthew Twomey20:11:53

and in my function, I have a let and that let has its own bindings. I though it would be nice to just “combine” the pre-defined params into that let binding so that I could refer to them directly.

Alex Miller (Clojure team)20:11:16

you can destructure to get that

Matthew Twomey20:11:22

(let [ [:code-challenge :code-verifier] (company_auth_params :dev) more stuf…]

Alex Miller (Clojure team)20:11:23

(let [{:keys [code-challenge verifier client_id]} (:dev company_auth_params)]
  ...)

Matthew Twomey20:11:03

aha! Even better, thank you sir this is super helpful. Trying now.

Matthew Twomey21:11:32

That worked awesome, thanks @U064X3EF3 👍

Matthew Twomey21:11:33

It has been happy Clojureing indeed 🙂

Alex Miller (Clojure team)21:11:15

btw you can learn more about destructuring in the guide https://clojure.org/guides/destructuring

🙌 1
👍 1