Fork me on GitHub
#beginners
<
2022-06-30
>
cheeze200003:06:02

hello, i have this function

defn f [a b & c] (println c)
is there a reason why (f 1 2) prints nil instead of an empty list

Ben Sless03:06:48

Println returns nil

hiredman03:06:06

Vargs are a seq not a list, technically

hiredman03:06:21

And while there is such thing as an empty seq now in clojure, it wasn't always the case, there was only nil

hiredman03:06:58

And in many cases and places things still operate like that is the case, and it is mostly fine

cheeze200004:06:02

@UK0810AQ2 it prints 2 nils, first nil being the c and the second being the return value of println

Ben Sless04:06:32

@U03N4NQ0PCH aye, my bad, misread the question, sorry

cheeze200004:06:53

also, i'm trying to replicate the + function by defining anonymous functions

(def sum2 #(+ %&))

(sum2 1 2 3)
why does it throw this error?
Execution error (ClassCastException) at java.lang.Class/cast (Class.java:3889).
Cannot cast clojure.lang.ArraySeq to java.lang.Number

hiredman04:06:38

%& is a seq of the rest of the arguments

hiredman04:06:44

And + operates on numbers, not seqs of numbers

cheeze200004:06:52

ohhh, ok thanks

Michaël Salihi05:06:55

So apply is what you want.

(def sum2 #(apply + %&))

cheeze200005:06:04

i see, thank you

peterh08:06:18

Btw, I never noticed it before, but (apply + nil) as well as (apply + '()) and (+) return 0, so nil behaves like an empty sequence here (which would be consistent to the behaviour of the empty vararg in your previous question). But (+ nil) returns nil.

Michaël Salihi09:06:00

(apply + nil) should be (apply + '(nil)) to be the equivalent to (+ nil). And its returns nil.

peterh10:06:21

Yeah it does make sense. I just find it a bit weird that nil and '() work the same way in args given that in Clojure they are not equal like in some other Lisps.

Michaël Salihi11:06:30

OK I see, interesting catch indeed.

dumrat07:06:02

I have a rest endpoint function like this:

(defn get-user-details
  [{:keys [userid]}]
  {:userid userid
   :result {:details (j/execute-one! (make-db) (get-user-details-normal-exp userid))
            :roles (j/execute (make-db) (get-user-roles-normal-exp userid))
            :functions (j/execute (make-db) (get-user-functions-normal-exp userid))}})
The three keys inside :result are populated using db select queries. How can I parallelize this?

Ben Wadsworth15:06:44

I think your question is a bit opaque. Clojure maps values are not realized until accessed. So your map, until you call something like ((get-in (get-user-details 123) [:result :details])) will never have actually called the database. its at that point you would call the execute command. If you want to force the queries to run when you call the function, you can wrap your functions with doall and that will force them to execute. The parallel part however is not handled here. You could use pmap to iterate over the functions you want to call then it would be paralleled. However, I think parallelizing query calls like this might be a bit of a code smell. At least to me, it seems like something would be off if doing this.

Ben Wadsworth15:06:59

I may have been mistaken, one second while I look into this again

Ben Wadsworth16:06:35

Right so, maps are eager but map is not which is where I got confused. Parallelizing the executions is something you could do in some form with https://clojuredocs.org/clojure.core/pmap

popeye08:06:36

I have below line of code , How do you sort-by according to :uri ?

(def p (group-by :uri [{:user-id 1 :uri "/zinc"}
                           {:user-id 2 :uri "/account"}
                           {:user-id 1 :uri "/foo"}])
  )

delaguardo08:06:00

what do you want to sort? the result of group-by or values of the result?

popeye08:06:21

basically if the map is as below , i would like to do a group-by first and then apply sort for uri which is of type string

(def a [{:user-id 1 :uri "/zinc"}
        {:user-id 2 :uri "/account"}
        {:user-id 1 :uri "/foo"}])

delaguardo08:06:25

(group-by :uri a) will give you a map of uri to the list of maps. How do you expect it to be sorted?

delaguardo09:06:01

(def my-maps
    [{:name "jess", :age 32} 
     {:name "ruxpin", :age 4} 
     {:name "jess", :age 35} 
     {:name "aero", :age 33} 
     {:name "banner", :age 4}])

(update-vals (group-by :name (sort-by :age my-maps)) last)
I can answer on the question from stackoverflow. But for your original question I still need more information 🙂

popeye09:06:03

Thanks @U04V4KLKC, What information you need ?

delaguardo09:06:03

> (group-by :uri a) will give you a map of uri to the list of maps. How do you expect it to be sorted?

popeye09:06:01

hmmmmm, how that is being sorted in stackoverflow? i am writing the code referring stack flow post,

sansarip14:06:07

This is going to be the result of your group-by with uri 👇

{"/zinc" [{:user-id 1, :uri "/zinc"}], 
 "/account" [{:user-id 2, :uri "/account"}], 
 "/foo" [{:user-id 1, :uri "/foo"}]}
Sorting here by uri doesn’t really make much sense since each vector will already be sorted by identical uri values :thinking_face: If you want the map keys to be sorted than you can use a https://clojuredocs.org/clojure.core/sorted-map. I think it’d be helpful if you write what your input data is and what you’d like your desired output data to be :thumbsup: