Fork me on GitHub
#beginners
<
2022-07-14
>
Tumi Ngobeni12:07:35

Good day everyone, I am new to Clojure, a complete beginner. I was wondering if there is a blueprint one can use to get in, I am beginning a new job but I am looking to start from the ground up. Like a complete beginner

Tumi Ngobeni13:07:18

@U01M742UT8F much appreciated, thank you very much

vanelsas13:07:16

np, it is a good start, there is lots more if needed

teodorlu13:07:20

Brave Clojure is good! Two additional recommendations. If you're going to use Visual Studio Code, the https://calva.io/getting-started/ guide is excellent. That will help you both with how to use the devlopment environment, and get you started writing some Clojure. See #calva for Calva / VSCode questions. Once you've been able to evaluate some Clojure, I'd check out https://clojure.org/guides/getting_started. Happy hacking!

domparry14:07:50

@U03PG4VKZ7B, I see you. You legend.

dorab16:07:44

Also check out the #the-clouncil channel on this Slack.

💯 1
naxels20:07:55

Hi all, I’m trying to decode/decipher a solution to a problem I would want to solve a completely different way, Here is the topic I posted in the discussion section of the person’s blog: https://github.com/jmglov/jmglov.net/discussions/2

naxels20:07:55

On this link: https://jmglov.net/blog/2022-07-06-hacking-blog-categories.html he goes about turning a list of maps containing sets (:categories) into a map of category as key and blog posts as values

naxels20:07:25

When I would see such a challenge, my first thinking would turn to group-by which I found out, fails pretty quickly

naxels20:07:47

Then I would likely turn to reduce and begin plowing through ways to ultimately get to the result I’m after

naxels20:07:33

but his solution as seen above is so simple using mapcat with a function, after which an easy reduce solves it all

naxels20:07:47

I can’t seem to figure out what reasoning leads to this solution..

naxels20:07:49

what am I missing?

naxels20:07:40

I totally get that you have to think about data transformation using functions and getting from A->B, but in this case I would rather quickly hit a road block

hiredman21:07:00

(for [{:keys [categories] :as post} sort-output category categories] [category post]) is the same thing has the mapcat with the nested map

hiredman21:07:40

and likely what I would write first, and then maybe pull apart into using map/mapcat/filter if I wanted to turn it into a transducer or something

naxels21:07:25

that works like a charm after updating sort-output to the correct def name

naxels21:07:34

could you walk me through a bit of your reasoning here?

naxels21:07:45

what makes you think for loop in this case

naxels21:07:53

where I was thinking group-by / reduce

hiredman21:07:55

well, first off, for is not a loop

naxels21:07:01

list comprehension

naxels21:07:40

i even tried to create a reduce fn with a sub loop/recur to walk through all category in categories, and failed

hiredman21:07:53

and to be fair, I didn't think through the problem, and come with for, I just happen to know that a map inside a mapcat is a for

hiredman21:07:05

so I went backwards

naxels21:07:06

haha, experience

hiredman21:07:47

I use for a lot for this sort of stuff, at least initially

hiredman21:07:11

it is good for navigating through structures and return a list of results

naxels21:07:23

i tend to stay away from (for , as when I first came to functional programming etc, it was all about unlearning manual looping mechanisms

naxels21:07:40

so i haven’t fully comprehended (pun intended) (for yet

hiredman21:07:07

writing a for is a lot like writing a sql query (I often end up mixing up when and where because for uses when and sql uses where)

1
hiredman21:07:09

for is in no way an imperative loop, just an unfortunate name clash

naxels21:07:54

so when I see this on clojuredocs:

naxels21:07:04

;; produce a seq of squares
(for [x (range 6)] 
  (* x x))
;;=> (0 1 4 9 16 25)

naxels21:07:09

i immediately think, why not:

naxels21:07:17

(map #(* % %) (range 6))
(0 1 4 9 16 25)

naxels21:07:04

I’m trying to understand how I can get it in my head that using (for might be a good idea for this kind of problem

hiredman21:07:08

it is basically the same thing

hiredman21:07:47

for really shines as you start to nest

hiredman21:07:21

you can think of each clause in a for as a nested mapping inside the mapping above it

hiredman21:07:46

and the nesting is what makes for good for traversing down into trees

naxels21:07:57

like how in (let [] you can use the first assigned immediately in the next assigned?

naxels21:07:09

(let [a 10 b (* 2 a)]

hiredman21:07:12

in a much more complicated way

respatialized21:07:55

Biggest difference with for at one level deep is with multiple sequence bindings: you get cross product semantics for the two sequences, whereas with map it's "zipping" the two together elementwise.

hiredman21:07:17

ok, so for is for building values in the sequence monad and let basically does the same thing for the identity monad

👁️ 1
naxels21:07:51

that helps me with the 2nd step in the transformation from A-B, thank you

naxels21:07:14

do you also know why in the intermediate output from step 2, you’d want the vector?

naxels21:07:26

to then use in step 3 the reduce to turn into the final conj’d map?

naxels21:07:08

like I would want to try to turn it straight into the map

hiredman21:07:26

a vector is just an easy way to convey multiple bits of information between steps

naxels21:07:49

in clojure i tend to use vectors very often indeed haha

hiredman21:07:15

I might have gone strait to a map as well, and then apply merge-with into

hiredman21:07:03

so construct a bunch of maps like {category [post]} and then merge them

hiredman21:07:35

the vector approach is likely a little more efficient, it sort of breaks things down into small parts and rebuilds, and with the map approach you build a more complicated structure the same shape as the result you want, then merge them, where merging has to break down the more complicated structure again

naxels21:07:16

i see, prefer simple/easier to understand where possible i guess

naxels21:07:40

thank you very much for your help, i’ve added an exercise for myself to try your apply merge-with into as well

naxels21:07:55

(merge-with into
	  {"Lisp" ["Common Lisp" "Clojure"]
	   "ML" ["Caml" "Objective Caml"]}
	  {"Lisp" ["Scheme"]
	   "ML" ["Standard ML"]})
;;=> {"Lisp" ["Common Lisp" "Clojure" "Scheme"], "ML" ["Caml" "Objective Caml" "Standard ML"]}
ha, the first example from clojuredocs shows exactly what you are talking about